[Feat] Upgrade Spotless from 6.16 to 6.25 (Breaking change) (#1068)

* remove 2nd subproject.spotless

* make linea-sequencer lint command, do lint command of child projects

* bump spotless to 6.25

* bump ktlint to 0.50.0

* run spotlessApply

* fix spotlessCheck for testing-tools:app

* spotless apply for many kt projects

* spotless apply for many kt projects

* set trailing comma to false in .editorconfig for kt files

* add more .editorconfig settings

* Revert "add more .editorconfig settings"

This reverts commit bd9f040f950930a662e8f815c5d504b3b4403703.

* Revert "set trailing comma to false in .editorconfig for kt files"

This reverts commit 4bcc08aa295c4da8d0bef2c75cf3fe621e0a00ae.

* empty
This commit is contained in:
kyzooghost
2025-06-03 00:02:21 +10:00
committed by GitHub
parent 19735ced28
commit cce0126d90
530 changed files with 5055 additions and 4956 deletions

View File

@@ -29,7 +29,7 @@ class LineaL1FinalizationTagUpdaterPlugin : BesuPlugin {
service = LineaL1FinalizationUpdaterService(
vertx,
cliOptions.getConfig(),
LineaBesuEngineBlockTagUpdater(blockchainService)
LineaBesuEngineBlockTagUpdater(blockchainService),
)
service.start()
}

View File

@@ -16,7 +16,7 @@ import kotlin.time.Duration.Companion.seconds
data class FinalizationUpdatePollerConfig(
val pollingInterval: Duration = 12.seconds,
val blockTag: BlockParameter
val blockTag: BlockParameter,
) {
init {
require(pollingInterval >= 0.seconds) {
@@ -30,18 +30,18 @@ class FinalizationUpdatePoller(
private val config: FinalizationUpdatePollerConfig,
private val lineaRollup: Web3JLineaRollupSmartContractClientReadOnly,
private val finalizationHandler: (ULong) -> CompletableFuture<*>,
private val log: Logger = LogManager.getLogger(FinalizationUpdatePoller::class.java)
private val log: Logger = LogManager.getLogger(FinalizationUpdatePoller::class.java),
) : PeriodicPollingService(
vertx = vertx,
pollingIntervalMs = config.pollingInterval.inWholeMilliseconds,
log = log
log = log,
) {
private val lastFinalizationRef: AtomicReference<ULong> = AtomicReference(null)
override fun action(): SafeFuture<*> {
return AsyncRetryer.retry(
vertx,
backoffDelay = config.pollingInterval
backoffDelay = config.pollingInterval,
) {
lineaRollup.finalizedL2BlockNumber(config.blockTag)
.thenCompose { lineaFinalizedBlockNumber ->
@@ -61,7 +61,7 @@ class FinalizationUpdatePoller(
if (error.cause is UnsupportedOperationException) {
log.error(
"\"setFinalizedBlock\" and \"setSafeBlock\" methods are not supported in the hosting Besu client, " +
"the poller will stop now, please check the Besu client's settings"
"the poller will stop now, please check the Besu client's settings",
)
super.stop()
} else {

View File

@@ -28,7 +28,7 @@ class LineaBesuEngineBlockTagUpdater(private val blockchainService: BlockchainSe
log.info(
"Linea safe/finalized block update: blockNumber={} blockHash={}",
finalizedBlockNumber,
blockHash
blockHash,
)
blockchainService.setSafeBlock(blockHash)
blockchainService.setFinalizedBlock(blockHash)
@@ -40,7 +40,7 @@ class LineaBesuEngineBlockTagUpdater(private val blockchainService: BlockchainSe
log.error(
"Linea safe/finalized block update failure: Method not supported or not enabled for PoS network: " +
"setFinalizedBlock and setSafeBlock",
e
e,
)
throw e
} catch (e: Exception) {
@@ -54,7 +54,7 @@ class LineaBesuEngineBlockTagUpdater(private val blockchainService: BlockchainSe
}
override fun lineaUpdateFinalizedBlockV1(
finalizedBlockNumber: Long
finalizedBlockNumber: Long,
) {
val updateSuccess = setFinalizedAndSafeBlock(finalizedBlockNumber)
log.debug("Linea safe/finalized block update: blockNumber={} success={}", finalizedBlockNumber, updateSuccess)
@@ -62,10 +62,10 @@ class LineaBesuEngineBlockTagUpdater(private val blockchainService: BlockchainSe
}
class LineaL1FinalizationUpdater(
private val engineBlockTagUpdater: EngineBlockTagUpdater
private val engineBlockTagUpdater: EngineBlockTagUpdater,
) {
fun handleL1Finalization(
finalizedBlockNumber: ULong
finalizedBlockNumber: ULong,
): CompletableFuture<Unit> {
runCatching {
engineBlockTagUpdater
@@ -80,28 +80,28 @@ class LineaL1FinalizationUpdater(
class LineaL1FinalizationUpdaterService(
vertx: Vertx,
config: PluginConfig,
engineBlockTagUpdater: EngineBlockTagUpdater
engineBlockTagUpdater: EngineBlockTagUpdater,
) : LongRunningService {
private val web3j = Web3j.build(
HttpService(
config.l1RpcEndpoint.toString(),
okHttpClientBuilder(LogManager.getLogger("clients.l1")).build()
)
okHttpClientBuilder(LogManager.getLogger("clients.l1")).build(),
),
)
private val lineaRollup = Web3JLineaRollupSmartContractClientReadOnly(
contractAddress = config.l1SmartContractAddress.toHexString(),
web3j = web3j
web3j = web3j,
)
private val updater = LineaL1FinalizationUpdater(engineBlockTagUpdater)
private val poller = FinalizationUpdatePoller(
vertx,
FinalizationUpdatePollerConfig(
pollingInterval = config.l1PollingInterval,
blockTag = BlockParameter.Tag.FINALIZED
blockTag = BlockParameter.Tag.FINALIZED,
),
lineaRollup,
updater::handleL1Finalization,
LogManager.getLogger(FinalizationUpdatePoller::class.java)
LogManager.getLogger(FinalizationUpdatePoller::class.java),
)
override fun start(): CompletableFuture<Unit> {

View File

@@ -11,7 +11,7 @@ import kotlin.time.toKotlinDuration
data class PluginConfig(
val l1SmartContractAddress: Address,
val l1RpcEndpoint: URL,
val l1PollingInterval: kotlin.time.Duration
val l1PollingInterval: kotlin.time.Duration,
) {
init {
require(l1PollingInterval >= 1.seconds) { "Polling interval=$l1PollingInterval must be greater that 1s." }
@@ -23,21 +23,21 @@ class PluginCliOptions {
names = ["--plugin-linea-l1-smart-contract-address"],
description = ["L1 smart contract address"],
required = true,
converter = [AddressConverter::class]
converter = [AddressConverter::class],
)
lateinit var l1SmartContractAddress: Address
@CommandLine.Option(
names = ["--plugin-linea-l1-rpc-endpoint"],
description = ["L1 RPC endpoint"],
required = true
required = true,
)
lateinit var l1RpcEndpoint: String
@CommandLine.Option(
names = ["--plugin-linea-l1-polling-interval"],
description = ["L1 polling interval"],
required = false
required = false,
)
var l1PollingInterval: Duration = Duration.ofSeconds(12)
@@ -45,14 +45,14 @@ class PluginCliOptions {
return PluginConfig(
l1SmartContractAddress = l1SmartContractAddress,
l1RpcEndpoint = URI(l1RpcEndpoint).toURL(),
l1PollingInterval = l1PollingInterval.toKotlinDuration()
l1PollingInterval = l1PollingInterval.toKotlinDuration(),
)
}
class AddressConverter : CommandLine.ITypeConverter<Address> {
override fun convert(value: String): Address {
return Address.fromHexString(value) ?: throw CommandLine.TypeConversionException(
"Invalid address: $value"
"Invalid address: $value",
)
}
}

View File

@@ -11,7 +11,7 @@ import kotlin.time.Duration.Companion.seconds
class FakeEngineBlockTagUpdater : EngineBlockTagUpdater {
override fun lineaUpdateFinalizedBlockV1(
finalizedBlockNumber: Long
finalizedBlockNumber: Long,
) {
println("Linea finalized block update: blockNumber=$finalizedBlockNumber")
}
@@ -23,7 +23,7 @@ fun main() {
val config = PluginConfig(
l1RpcEndpoint = URI("https://mainnet.infura.io/v3/$infuraAppKey").toURL(),
l1SmartContractAddress = Address.fromHexString("0xd19d4B5d358258f05D7B411E21A1460D11B0876F"),
l1PollingInterval = 1.seconds
l1PollingInterval = 1.seconds,
)
val service = LineaL1FinalizationUpdaterService(vertx, config, FakeEngineBlockTagUpdater())
service.start().get()

View File

@@ -33,6 +33,15 @@ licenseReport {
]
}
// Make the parent project's spotlessCheck depend on all subproject spotlessCheck tasks
afterEvaluate {
if (tasks.findByName('spotlessCheck')) {
spotlessCheck.dependsOn subprojects.collect { subproject ->
subproject.tasks.matching { task -> task.name == 'spotlessCheck' }
}
}
}
build {
dependsOn checkLicense
}

View File

@@ -6,7 +6,7 @@ import tech.pegasys.teku.infrastructure.async.SafeFuture
data class StateRecoveryStatus(
val headBlockNumber: ULong,
val stateRecoverStartBlockNumber: ULong?
val stateRecoverStartBlockNumber: ULong?,
)
interface ExecutionLayerClient {
fun getBlockNumberAndHash(blockParameter: BlockParameter): SafeFuture<BlockNumberAndHash>

View File

@@ -24,20 +24,20 @@ class InMemoryRecoveryStatus : RecoveryStatusPersistence {
}
class FileBasedRecoveryStatusPersistence(
filePath: Path
filePath: Path,
) : RecoveryStatusPersistence {
// A little future proofing in case we need to change the file format in the future
private enum class FileVersion {
V1 // note: do not rename because it will fail to parse the file if already written
V1, // note: do not rename because it will fail to parse the file if already written
}
private data class RecoveryStatusEnvelopeDto(
val version: FileVersion,
val recoveryStatus: RecoveryStatusV1Dto?
val recoveryStatus: RecoveryStatusV1Dto?,
)
private data class RecoveryStatusV1Dto(
val recoveryStartBlockNumber: ULong
val recoveryStartBlockNumber: ULong,
)
private val objectMapper = jacksonObjectMapper()
private val file = filePath.toFile()
@@ -46,8 +46,8 @@ class FileBasedRecoveryStatusPersistence(
private fun saveToFile(status: RecoveryStatusV1Dto?) {
file.writeText(
objectMapper.writeValueAsString(
RecoveryStatusEnvelopeDto(FileVersion.V1, status)
)
RecoveryStatusEnvelopeDto(FileVersion.V1, status),
),
)
}

View File

@@ -13,7 +13,7 @@ class FileRecoveryStatusPersistenceTest {
@Test
fun `should return null when no recovery start block number is saved`(
@TempDir tempDir: Path
@TempDir tempDir: Path,
) {
val recoveryStatusPersistence = FileBasedRecoveryStatusPersistence(tempDir.resolve("recovery-status.json"))
assertThat(recoveryStatusPersistence.getRecoveryStartBlockNumber()).isNull()
@@ -21,7 +21,7 @@ class FileRecoveryStatusPersistenceTest {
@Test
fun `should return the saved recovery start block number`(
@TempDir tempDir: Path
@TempDir tempDir: Path,
) {
FileBasedRecoveryStatusPersistence(tempDir.resolve("recovery-status.json"))
.also { persistence ->
@@ -46,7 +46,7 @@ class FileRecoveryStatusPersistenceTest {
@Test
fun `shall throw when it cannot create the file`(
@TempDir tempDir: Path
@TempDir tempDir: Path,
) {
val dirWithoutWritePermissions = tempDir.resolve("dir-without-write-permissions")
@@ -64,7 +64,7 @@ class FileRecoveryStatusPersistenceTest {
@Test
fun `should throw error when file version is not supported`(
@TempDir tempDir: Path
@TempDir tempDir: Path,
) {
val invalidJsonPayload = """
{

View File

@@ -9,7 +9,7 @@ data class BlockHeaderFromL1RecoveredData(
val coinbase: ByteArray,
val blockTimestamp: Instant,
val gasLimit: ULong,
val difficulty: ULong
val difficulty: ULong,
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
@@ -51,7 +51,7 @@ data class BlockHeaderFromL1RecoveredData(
data class BlockFromL1RecoveredData(
val header: BlockHeaderFromL1RecoveredData,
val transactions: List<TransactionFromL1RecoveredData>
val transactions: List<TransactionFromL1RecoveredData>,
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true

View File

@@ -14,12 +14,12 @@ data class TransactionFromL1RecoveredData(
val to: ByteArray?,
val value: BigInteger,
val data: ByteArray?,
val accessList: List<AccessTuple>?
val accessList: List<AccessTuple>?,
) {
data class AccessTuple(
val address: ByteArray,
val storageKeys: List<ByteArray>
val storageKeys: List<ByteArray>,
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true

View File

@@ -24,18 +24,18 @@ interface BlobDecompressorAndDeserializer {
*/
fun decompress(
startBlockNumber: ULong,
blobs: List<ByteArray>
blobs: List<ByteArray>,
): SafeFuture<List<BlockFromL1RecoveredData>>
}
data class BlockHeaderStaticFields(
val coinbase: ByteArray,
val gasLimit: ULong = 2_000_000_000UL,
val difficulty: ULong = 2UL
val difficulty: ULong = 2UL,
) {
companion object {
val localDev = BlockHeaderStaticFields(
coinbase = "0x6d976c9b8ceee705d4fe8699b44e5eb58242f484".decodeHex()
coinbase = "0x6d976c9b8ceee705d4fe8699b44e5eb58242f484".decodeHex(),
)
}
@@ -69,11 +69,11 @@ class BlobDecompressorToDomainV1(
val staticFields: BlockHeaderStaticFields,
val vertx: Vertx,
val decoder: BinaryDecoder<Block> = BesuRlpBlobDecoder,
val logger: Logger = LogManager.getLogger(BlobDecompressorToDomainV1::class.java)
val logger: Logger = LogManager.getLogger(BlobDecompressorToDomainV1::class.java),
) : BlobDecompressorAndDeserializer {
override fun decompress(
startBlockNumber: ULong,
blobs: List<ByteArray>
blobs: List<ByteArray>,
): SafeFuture<List<BlockFromL1RecoveredData>> {
var blockNumber = startBlockNumber
val startTime = Clock.System.now()
@@ -89,7 +89,7 @@ class BlobDecompressorToDomainV1(
coinbase = staticFields.coinbase,
blockTimestamp = Instant.fromEpochSeconds(block.header.timestamp),
gasLimit = this.staticFields.gasLimit,
difficulty = this.staticFields.difficulty
difficulty = this.staticFields.difficulty,
)
val transactions = block.body.transactions.map { transaction ->
TransactionFromL1RecoveredData(
@@ -106,14 +106,14 @@ class BlobDecompressorToDomainV1(
accessList = transaction.accessList.getOrNull()?.map { accessTuple ->
TransactionFromL1RecoveredData.AccessTuple(
address = accessTuple.address.toArray(),
storageKeys = accessTuple.storageKeys.map { it.toArray() }
storageKeys = accessTuple.storageKeys.map { it.toArray() },
)
}
},
)
}
BlockFromL1RecoveredData(
header = header,
transactions = transactions
transactions = transactions,
)
}
}.thenPeek {
@@ -122,7 +122,7 @@ class BlobDecompressorToDomainV1(
"blobs decompressed and serialized: duration={} blobsCount={} blocks={}",
endTime - startTime,
blobs.size,
CommonDomainFunctions.blockIntervalString(startBlockNumber, blockNumber - 1UL)
CommonDomainFunctions.blockIntervalString(startBlockNumber, blockNumber - 1UL),
)
}
}
@@ -130,7 +130,7 @@ class BlobDecompressorToDomainV1(
private fun decodeBlocksAsync(blocksRLP: ByteArray): SafeFuture<List<Block>> {
return vertx.executeBlocking(
Callable { RLP.decodeList(blocksRLP).map(decoder::decode) },
false
false,
)
.onFailure(logger::error)
.toSafeFuture()

View File

@@ -10,7 +10,7 @@ import kotlin.time.Duration.Companion.seconds
data class ImportResult(
val blockNumber: ULong,
val zkStateRootHash: ByteArray
val zkStateRootHash: ByteArray,
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
@@ -39,7 +39,7 @@ class BlockImporterAndStateVerifierV1(
private val vertx: Vertx,
private val elClient: ExecutionLayerClient,
private val stateManagerClient: StateManagerClientV1,
private val stateManagerImportTimeoutPerBlock: Duration
private val stateManagerImportTimeoutPerBlock: Duration,
) : BlockImporterAndStateVerifier {
override fun importBlocks(blocks: List<BlockFromL1RecoveredData>): SafeFuture<ImportResult> {
val sortedBlocks = blocks.sortedBy { it.header.blockNumber }
@@ -49,20 +49,20 @@ class BlockImporterAndStateVerifierV1(
.thenCompose {
getBlockStateRootHash(
blockNumber = lastBlockNumber,
timeout = stateManagerImportTimeoutPerBlock.times(blocks.size)
timeout = stateManagerImportTimeoutPerBlock.times(blocks.size),
)
}
.thenApply { stateRootHash ->
ImportResult(
blockNumber = lastBlockNumber,
zkStateRootHash = stateRootHash
zkStateRootHash = stateRootHash,
)
}
}
private fun getBlockStateRootHash(
blockNumber: ULong,
timeout: Duration
timeout: Duration,
): SafeFuture<ByteArray> {
return AsyncRetryer
.retry(
@@ -70,7 +70,7 @@ class BlockImporterAndStateVerifierV1(
backoffDelay = 1.seconds,
timeout = timeout,
stopRetriesPredicate = { headBlockNumber -> headBlockNumber >= blockNumber },
action = { stateManagerClient.rollupGetHeadBlockNumber() }
action = { stateManagerClient.rollupGetHeadBlockNumber() },
)
.thenCompose {
stateManagerClient.rollupGetStateMerkleProof(BlockInterval(blockNumber, blockNumber))

View File

@@ -12,7 +12,7 @@ import tech.pegasys.teku.infrastructure.async.SafeFuture
data class DataSubmittedV3(
val parentShnarf: ByteArray,
val shnarf: ByteArray,
val finalStateRootHash: ByteArray
val finalStateRootHash: ByteArray,
) {
companion object {
val topic = "0x55f4c645c36aa5cd3f443d6be44d7a7a5df9d2100d7139dfc69d4289ee072319"
@@ -22,9 +22,9 @@ data class DataSubmittedV3(
event = DataSubmittedV3(
parentShnarf = ethLog.data.sliceOf32(0),
shnarf = ethLog.topics[1],
finalStateRootHash = ethLog.data.sliceOf32(1)
finalStateRootHash = ethLog.data.sliceOf32(1),
),
log = ethLog
log = ethLog,
)
}
}
@@ -62,7 +62,7 @@ data class DataFinalizedV3(
override val endBlockNumber: ULong,
val shnarf: ByteArray,
val parentStateRootHash: ByteArray,
val finalStateRootHash: ByteArray
val finalStateRootHash: ByteArray,
) : BlockInterval {
companion object {
val topic = "0xa0262dc79e4ccb71ceac8574ae906311ae338aa4a2044fd4ec4b99fad5ab60cb"
@@ -81,9 +81,9 @@ data class DataFinalizedV3(
endBlockNumber = ethLog.topics[2].toULongFromLast8Bytes(),
shnarf = ethLog.topics[3],
parentStateRootHash = dataBytes.sliceOf32(sliceNumber = 0),
finalStateRootHash = dataBytes.sliceOf32(sliceNumber = 1)
finalStateRootHash = dataBytes.sliceOf32(sliceNumber = 1),
),
log = ethLog
log = ethLog,
)
}
}
@@ -124,17 +124,17 @@ data class DataFinalizedV3(
data class FinalizationAndDataEventsV3(
val dataSubmittedEvents: List<EthLogEvent<DataSubmittedV3>>,
val dataFinalizedEvent: EthLogEvent<DataFinalizedV3>
val dataFinalizedEvent: EthLogEvent<DataFinalizedV3>,
)
interface LineaRollupSubmissionEventsClient {
fun findFinalizationAndDataSubmissionV3Events(
fromL1BlockNumber: BlockParameter,
finalizationStartBlockNumber: ULong
finalizationStartBlockNumber: ULong,
): SafeFuture<FinalizationAndDataEventsV3?>
fun findFinalizationAndDataSubmissionV3EventsContainingL2BlockNumber(
fromL1BlockNumber: BlockParameter,
l2BlockNumber: ULong
l2BlockNumber: ULong,
): SafeFuture<FinalizationAndDataEventsV3?>
}

View File

@@ -13,7 +13,7 @@ class LineaSubmissionEventsClientImpl(
private val logsSearcher: EthLogsSearcher,
private val smartContractAddress: String,
private val l1LatestSearchBlock: BlockParameter = BlockParameter.Tag.FINALIZED,
private val logsBlockChunkSize: Int
private val logsBlockChunkSize: Int,
) : LineaRollupSubmissionEventsClient {
init {
require(logsBlockChunkSize > 0) { "logsBlockChunkSize=$logsBlockChunkSize must be greater than 0" }
@@ -21,7 +21,7 @@ class LineaSubmissionEventsClientImpl(
private fun findDataFinalizedEventContainingBlock(
fromBlock: BlockParameter,
l2BlockNumber: ULong
l2BlockNumber: ULong,
): SafeFuture<EthLogEvent<DataFinalizedV3>?> {
return logsSearcher.findLog(
fromBlock = fromBlock,
@@ -36,18 +36,18 @@ class LineaSubmissionEventsClientImpl(
l2BlockNumber > event.endBlockNumber -> SearchDirection.FORWARD
else -> null
}
}
},
).thenApply { it?.let { DataFinalizedV3.fromEthLog(it) } }
}
override fun findFinalizationAndDataSubmissionV3Events(
fromL1BlockNumber: BlockParameter,
finalizationStartBlockNumber: ULong
finalizationStartBlockNumber: ULong,
): SafeFuture<FinalizationAndDataEventsV3?> {
return findDataFinalizedV3Event(
fromL1BlockNumber = fromL1BlockNumber,
toL1BlockNumber = l1LatestSearchBlock,
startBlockNumber = finalizationStartBlockNumber
startBlockNumber = finalizationStartBlockNumber,
)
.thenCompose { finalizationEvent ->
finalizationEvent
@@ -63,7 +63,7 @@ class LineaSubmissionEventsClientImpl(
override fun findFinalizationAndDataSubmissionV3EventsContainingL2BlockNumber(
fromL1BlockNumber: BlockParameter,
l2BlockNumber: ULong
l2BlockNumber: ULong,
): SafeFuture<FinalizationAndDataEventsV3?> {
return findDataFinalizedEventContainingBlock(fromL1BlockNumber, l2BlockNumber)
.thenCompose { finalizationEvent ->
@@ -82,7 +82,7 @@ class LineaSubmissionEventsClientImpl(
fromL1BlockNumber: BlockParameter,
toL1BlockNumber: BlockParameter,
startBlockNumber: ULong? = null,
endBlockNumber: ULong? = null
endBlockNumber: ULong? = null,
): SafeFuture<EthLogEvent<DataFinalizedV3>?> {
assert(startBlockNumber != null || endBlockNumber != null) {
"Either startBlockNumber or endBlockNumber must be provided"
@@ -104,8 +104,8 @@ class LineaSubmissionEventsClientImpl(
topics = listOf(
DataFinalizedV3.topic,
startBlockNumber?.toHexStringUInt256(),
endBlockNumber?.toHexStringUInt256()
)
endBlockNumber?.toHexStringUInt256(),
),
).thenCompose { rawLogs ->
val finalizedEvents = rawLogs.map(DataFinalizedV3::fromEthLog)
@@ -122,7 +122,7 @@ class LineaSubmissionEventsClientImpl(
}
private fun findAggregationDataSubmittedV3Events(
finalizationEvent: EthLogEvent<DataFinalizedV3>
finalizationEvent: EthLogEvent<DataFinalizedV3>,
): SafeFuture<List<EthLogEvent<DataSubmittedV3>>> {
val dataEvents = mutableListOf<EthLogEvent<DataSubmittedV3>>()
val futureResult = SafeFuture<List<EthLogEvent<DataSubmittedV3>>>()
@@ -140,7 +140,7 @@ class LineaSubmissionEventsClientImpl(
findDataSubmittedV3EventByShnarf(
fromL1BlockParameter = BlockParameter.Tag.EARLIEST,
tol1BlockParameter = dataSubmission.log.blockNumber.toLong().toBlockParameter(),
shnarf = dataSubmission.event.parentShnarf
shnarf = dataSubmission.event.parentShnarf,
).thenPeek(::fetchParentDataSubmission)
}
}
@@ -148,7 +148,7 @@ class LineaSubmissionEventsClientImpl(
getDataSubmittedV3EventByShnarf(
fromL1BlockParameter = BlockParameter.Tag.EARLIEST,
tol1BlockParameter = finalizationEvent.log.blockNumber.toLong().toBlockParameter(),
shnarf = finalizationEvent.event.shnarf
shnarf = finalizationEvent.event.shnarf,
).thenPeek(::fetchParentDataSubmission)
return futureResult
@@ -157,7 +157,7 @@ class LineaSubmissionEventsClientImpl(
private fun getDataSubmittedV3EventByShnarf(
fromL1BlockParameter: BlockParameter,
tol1BlockParameter: BlockParameter,
shnarf: ByteArray
shnarf: ByteArray,
): SafeFuture<EthLogEvent<DataSubmittedV3>> {
return findDataSubmittedV3EventByShnarf(fromL1BlockParameter, tol1BlockParameter, shnarf)
.thenApply { event ->
@@ -168,7 +168,7 @@ class LineaSubmissionEventsClientImpl(
private fun findDataSubmittedV3EventByShnarf(
fromL1BlockParameter: BlockParameter,
tol1BlockParameter: BlockParameter,
shnarf: ByteArray
shnarf: ByteArray,
): SafeFuture<EthLogEvent<DataSubmittedV3>?> {
return logsSearcher
.getLogs(
@@ -177,8 +177,8 @@ class LineaSubmissionEventsClientImpl(
address = smartContractAddress,
topics = listOf(
DataSubmittedV3.topic,
shnarf.encodeHex()
)
shnarf.encodeHex(),
),
)
.thenApply { rawLogs ->
val events = rawLogs.map(DataSubmittedV3::fromEthLog)

View File

@@ -12,28 +12,28 @@ import kotlin.time.Duration.Companion.seconds
class LookBackBlockHashesFetcher(
private val vertx: Vertx,
private val elClient: ExecutionLayerClient,
private val submissionsFetcher: SubmissionsFetchingTask
private val submissionsFetcher: SubmissionsFetchingTask,
) {
fun getLookBackHashes(
status: StateRecoveryStatus
status: StateRecoveryStatus,
): SafeFuture<Map<ULong, ByteArray>> {
val intervals = lookbackFetchingIntervals(
headBlockNumber = status.headBlockNumber,
recoveryStartBlockNumber = status.stateRecoverStartBlockNumber,
lookbackWindow = 256UL
lookbackWindow = 256UL,
)
return SafeFuture.collectAll(
listOf(
intervals.elInterval?.let(::getLookBackHashesFromLocalEl) ?: SafeFuture.completedFuture(emptyMap()),
intervals.l1Interval?.let(::getLookBackHashesFromL1) ?: SafeFuture.completedFuture(emptyMap())
).stream()
intervals.l1Interval?.let(::getLookBackHashesFromL1) ?: SafeFuture.completedFuture(emptyMap()),
).stream(),
)
.thenApply { (blockHashesFromEl, blockHashesFromL1) -> blockHashesFromEl + blockHashesFromL1 }
}
fun getLookBackHashesFromLocalEl(
blockInterval: BlockInterval
blockInterval: BlockInterval,
): SafeFuture<Map<ULong, ByteArray>> {
return SafeFuture
.collectAll(blockInterval.blocksRange.map { elClient.getBlockNumberAndHash(it.toBlockParameter()) }.stream())
@@ -43,7 +43,7 @@ class LookBackBlockHashesFetcher(
}
fun getLookBackHashesFromL1(
blockInterval: BlockInterval
blockInterval: BlockInterval,
): SafeFuture<Map<ULong, ByteArray>> {
return AsyncRetryer.retry(
vertx,
@@ -51,7 +51,7 @@ class LookBackBlockHashesFetcher(
stopRetriesPredicate = { submissions ->
submissions.isNotEmpty() &&
submissions.last().submissionEvents.dataFinalizedEvent.event.endBlockNumber >= blockInterval.endBlockNumber
}
},
) {
// get the data without removing it from the queue
// it must still be in the queue until is imported to the EL
@@ -75,7 +75,7 @@ class LookBackBlockHashesFetcher(
fun shallIncreaseQueueLimit(
availableSubmissions: List<SubmissionEventsAndData<BlockFromL1RecoveredData>>,
blockInterval: BlockInterval
blockInterval: BlockInterval,
): Boolean {
if (availableSubmissions.isEmpty()) {
return false

View File

@@ -6,7 +6,7 @@ import linea.kotlin.minusCoercingUnderflow
fun startBlockToFetchFromL1(
headBlockNumber: ULong,
recoveryStartBlockNumber: ULong?,
lookbackWindow: ULong
lookbackWindow: ULong,
): ULong {
if (recoveryStartBlockNumber == null) {
return headBlockNumber + 1UL
@@ -19,24 +19,24 @@ fun startBlockToFetchFromL1(
data class FetchingIntervals(
val elInterval: BlockInterval?,
val l1Interval: BlockInterval?
val l1Interval: BlockInterval?,
)
fun lookbackFetchingIntervals(
headBlockNumber: ULong,
recoveryStartBlockNumber: ULong?,
lookbackWindow: ULong
lookbackWindow: ULong,
): FetchingIntervals {
if (recoveryStartBlockNumber == null || recoveryStartBlockNumber > headBlockNumber) {
return FetchingIntervals(
l1Interval = null,
elInterval = BlockInterval(headBlockNumber.minusCoercingUnderflow(lookbackWindow - 1UL), headBlockNumber)
elInterval = BlockInterval(headBlockNumber.minusCoercingUnderflow(lookbackWindow - 1UL), headBlockNumber),
)
}
if (headBlockNumber - lookbackWindow > recoveryStartBlockNumber) {
return FetchingIntervals(
l1Interval = BlockInterval(headBlockNumber.minusCoercingUnderflow(lookbackWindow - 1UL), headBlockNumber),
elInterval = null
elInterval = null,
)
}
@@ -44,7 +44,7 @@ fun lookbackFetchingIntervals(
l1Interval = BlockInterval(recoveryStartBlockNumber, headBlockNumber),
elInterval = BlockInterval(
headBlockNumber.minusCoercingUnderflow(lookbackWindow - 1UL),
recoveryStartBlockNumber - 1UL
)
recoveryStartBlockNumber - 1UL,
),
)
}

View File

@@ -28,7 +28,7 @@ class StateRecoveryApp(
private val transactionDetailsClient: TransactionDetailsClient,
private val blockHeaderStaticFields: BlockHeaderStaticFields,
// configs
private val config: Config
private val config: Config,
) : LongRunningService {
data class Config(
val smartContractAddress: String,
@@ -43,7 +43,7 @@ class StateRecoveryApp(
* this is meant for testing purposes, not production
*/
val overridingRecoveryStartBlockNumber: ULong? = null,
val debugForceSyncStopBlockNumber: ULong? = null
val debugForceSyncStopBlockNumber: ULong? = null,
) {
companion object {
val lineaMainnet = Config(
@@ -53,7 +53,7 @@ class StateRecoveryApp(
l1LatestSearchBlock = BlockParameter.Tag.FINALIZED,
l1PollingInterval = 12.seconds,
l1getLogsChunkSize = 10_000u,
executionClientPollingInterval = 2.seconds
executionClientPollingInterval = 2.seconds,
)
val lineaSepolia = Config(
smartContractAddress = "0xb218f8a4bc926cf1ca7b3423c154a0d627bdb7e5",
@@ -61,7 +61,7 @@ class StateRecoveryApp(
l1LatestSearchBlock = BlockParameter.Tag.FINALIZED,
l1PollingInterval = 12.seconds,
l1getLogsChunkSize = 10_000u,
executionClientPollingInterval = 2.seconds
executionClientPollingInterval = 2.seconds,
)
}
}
@@ -76,19 +76,19 @@ class StateRecoveryApp(
logsSearcher = ethLogsSearcher,
smartContractAddress = config.smartContractAddress,
l1LatestSearchBlock = config.l1LatestSearchBlock,
logsBlockChunkSize = config.l1getLogsChunkSize.toInt()
logsBlockChunkSize = config.l1getLogsChunkSize.toInt(),
)
private val log = LogManager.getLogger(this::class.java)
private val blockImporterAndStateVerifier = BlockImporterAndStateVerifierV1(
vertx = vertx,
elClient = elClient,
stateManagerClient = stateManagerClient,
stateManagerImportTimeoutPerBlock = 2.seconds
stateManagerImportTimeoutPerBlock = 2.seconds,
)
private val blobDecompressor: BlobDecompressorAndDeserializer = BlobDecompressorToDomainV1(
decompressor = GoNativeBlobDecompressorFactory.getInstance(config.blobDecompressorVersion),
staticFields = blockHeaderStaticFields,
vertx = vertx
vertx = vertx,
)
private val stateSynchronizerService = StateSynchronizerService(
vertx = vertx,
@@ -100,7 +100,7 @@ class StateRecoveryApp(
blobDecompressor = blobDecompressor,
blockImporterAndStateVerifier = blockImporterAndStateVerifier,
pollingInterval = config.l1PollingInterval,
debugForceSyncStopBlockNumber = config.debugForceSyncStopBlockNumber
debugForceSyncStopBlockNumber = config.debugForceSyncStopBlockNumber,
)
val stateRootMismatchFound: Boolean
get() = stateSynchronizerService.stateRootMismatchFound
@@ -119,7 +119,7 @@ class StateRecoveryApp(
updateLabel,
newStatus.headBlockNumber,
statusBeforeUpdate.stateRecoverStartBlockNumber,
newStatus.stateRecoverStartBlockNumber
newStatus.stateRecoverStartBlockNumber,
)
}
}
@@ -138,7 +138,7 @@ class StateRecoveryApp(
log.info(
"starting recovery mode already enabled: stateRecoverStartBlockNumber={} headBlockNumber={}",
status.stateRecoverStartBlockNumber,
status.headBlockNumber
status.headBlockNumber,
)
SafeFuture.completedFuture(Unit)
} else {
@@ -153,7 +153,7 @@ class StateRecoveryApp(
"L1 lastFinalizedBlockNumber={}",
stateRecoverStartBlockNumber,
status.headBlockNumber,
lastFinalizedBlockNumber
lastFinalizedBlockNumber,
)
elClient.lineaEnableStateRecovery(stateRecoverStartBlockNumber)
}.thenApply { }
@@ -175,17 +175,17 @@ class StateRecoveryApp(
log.info(
"node reached recovery target block: stateRecoverStartBlockNumber={} headBlockNumber={}",
recoveryStatus.stateRecoverStartBlockNumber,
recoveryStatus.headBlockNumber
recoveryStatus.headBlockNumber,
)
} else {
log.info(
"waiting for node to sync until stateRecoverStartBlockNumber={} - 1, headBlockNumber={}",
recoveryStatus.stateRecoverStartBlockNumber,
recoveryStatus.headBlockNumber
recoveryStatus.headBlockNumber,
)
}
hasReachedTargetBlock
}
},
) {
elClient.lineaGetStateRecoveryStatus()
}

View File

@@ -22,11 +22,11 @@ class StateSynchronizerService(
private val blockImporterAndStateVerifier: BlockImporterAndStateVerifier,
private val pollingInterval: Duration,
private val debugForceSyncStopBlockNumber: ULong?,
private val log: Logger = LogManager.getLogger(StateSynchronizerService::class.java)
private val log: Logger = LogManager.getLogger(StateSynchronizerService::class.java),
) : PeriodicPollingService(
vertx = vertx,
log = log,
pollingIntervalMs = pollingInterval.inWholeMilliseconds
pollingIntervalMs = pollingInterval.inWholeMilliseconds,
) {
@get:Synchronized
@set:Synchronized
@@ -48,7 +48,7 @@ class StateSynchronizerService(
val l2StartBlockNumberToFetchInclusive = startBlockToFetchFromL1(
headBlockNumber = status.headBlockNumber,
recoveryStartBlockNumber = status.stateRecoverStartBlockNumber,
lookbackWindow = 256UL
lookbackWindow = 256UL,
)
this.blobsFetcherTask = SubmissionsFetchingTask(
@@ -63,7 +63,7 @@ class StateSynchronizerService(
submissionEventsQueueLimit = 10,
compressedBlobsQueueLimit = 10,
targetDecompressedBlobsQueueLimit = 10,
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber,
)
blobsFetcherTask.start()
}
@@ -91,7 +91,7 @@ class StateSynchronizerService(
val loobackHasheFetcher = LookBackBlockHashesFetcher(
vertx = vertx,
elClient = elClient,
submissionsFetcher = blobsFetcherTask
submissionsFetcher = blobsFetcherTask,
)
return this.elClient
@@ -116,30 +116,30 @@ class StateSynchronizerService(
if (blocksToImport.isEmpty()) {
log.debug(
"no blocks to import for finalization={}",
nexFinalization.submissionEvents.dataFinalizedEvent.event
nexFinalization.submissionEvents.dataFinalizedEvent.event,
)
return@thenCompose SafeFuture.completedFuture(Unit)
}
importBlocksAndAssertStateroot(
decompressedBlocksToImport = blocksToImport,
dataFinalizedV3 = nexFinalization.submissionEvents.dataFinalizedEvent.event
dataFinalizedV3 = nexFinalization.submissionEvents.dataFinalizedEvent.event,
)
}
.thenPeek {
blobsFetcherTask.pruneQueueForElementsUpToInclusive(
nexFinalization.submissionEvents.dataFinalizedEvent.event.endBlockNumber
nexFinalization.submissionEvents.dataFinalizedEvent.event.endBlockNumber,
)
}
}
private fun importBlocksAndAssertStateroot(
decompressedBlocksToImport: List<BlockFromL1RecoveredData>,
dataFinalizedV3: DataFinalizedV3
dataFinalizedV3: DataFinalizedV3,
): SafeFuture<Unit> {
val blockInterval = CommonDomainFunctions.blockIntervalString(
decompressedBlocksToImport.first().header.blockNumber,
decompressedBlocksToImport.last().header.blockNumber
decompressedBlocksToImport.last().header.blockNumber,
)
log.debug("importing blocks={} from finalization={}", blockInterval, dataFinalizedV3.intervalString())
return blockImporterAndStateVerifier
@@ -151,7 +151,7 @@ class StateSynchronizerService(
}
private fun filterOutBlocksAlreadyImportedAndBeyondStopSync(
blocks: List<BlockFromL1RecoveredData>
blocks: List<BlockFromL1RecoveredData>,
): SafeFuture<List<BlockFromL1RecoveredData>> {
return elClient.getBlockNumberAndHash(blockParameter = BlockParameter.Tag.LATEST)
.thenApply { headBlock ->
@@ -165,14 +165,14 @@ class StateSynchronizerService(
private fun assertStateMatches(
importResult: ImportResult,
finalizedV3: DataFinalizedV3
finalizedV3: DataFinalizedV3,
): SafeFuture<Unit> {
if (importResult.blockNumber != finalizedV3.endBlockNumber) {
log.info(
"cannot compare stateroot: last imported block={} finalization={} debugForceSyncStopBlockNumber={}",
importResult.blockNumber,
finalizedV3.intervalString(),
debugForceSyncStopBlockNumber
debugForceSyncStopBlockNumber,
)
if (importResult.blockNumber == debugForceSyncStopBlockNumber) {
// this means debugForceSyncStopBlockNumber was set and we stopped before reaching the target block
@@ -183,7 +183,7 @@ class StateSynchronizerService(
log.info(
"state recovered up to finalization={} zkStateRootHash={}",
finalizedV3.intervalString(),
importResult.zkStateRootHash.encodeHex()
importResult.zkStateRootHash.encodeHex(),
)
} else {
log.error(
@@ -193,7 +193,7 @@ class StateSynchronizerService(
finalizedV3.intervalString(),
importResult.blockNumber,
importResult.zkStateRootHash.encodeHex(),
finalizedV3.finalStateRootHash.encodeHex()
finalizedV3.finalStateRootHash.encodeHex(),
)
stateRootMismatchFound = true
this.stop()

View File

@@ -18,11 +18,11 @@ internal class BlobDecompressionTask(
private val rawBlobsQueue: ConcurrentLinkedQueue<SubmissionEventsAndData<ByteArray>>,
private val decompressedBlocksQueue: ConcurrentLinkedQueue<SubmissionEventsAndData<BlockFromL1RecoveredData>>,
private val decompressedFinalizationQueueLimit: Supplier<Int>,
private val log: Logger = LogManager.getLogger(SubmissionsFetchingTask::class.java)
private val log: Logger = LogManager.getLogger(SubmissionsFetchingTask::class.java),
) : PeriodicPollingService(
vertx = vertx,
pollingIntervalMs = pollingInterval.inWholeMilliseconds,
log = log
log = log,
) {
override fun action(): SafeFuture<*> {
return decompressAndDeserializeBlobs()
@@ -38,10 +38,10 @@ internal class BlobDecompressionTask(
return blobDecompressor
.decompress(
startBlockNumber = submissionEventsAndData.submissionEvents.dataFinalizedEvent.event.startBlockNumber,
blobs = submissionEventsAndData.data
blobs = submissionEventsAndData.data,
).thenCompose { decompressedBlocks ->
decompressedBlocksQueue.add(
SubmissionEventsAndData(submissionEventsAndData.submissionEvents, decompressedBlocks)
SubmissionEventsAndData(submissionEventsAndData.submissionEvents, decompressedBlocks),
)
decompressAndDeserializeBlobs()
}

View File

@@ -19,11 +19,11 @@ internal class BlobsFetchingTask(
private val submissionEventsQueue: ConcurrentLinkedQueue<FinalizationAndDataEventsV3>,
private val compressedBlobsQueue: ConcurrentLinkedQueue<SubmissionEventsAndData<ByteArray>>,
private val compressedBlobsQueueLimit: Int,
private val log: Logger = LogManager.getLogger(BlobsFetchingTask::class.java)
private val log: Logger = LogManager.getLogger(BlobsFetchingTask::class.java),
) : PeriodicPollingService(
vertx = vertx,
pollingIntervalMs = pollingInterval.inWholeMilliseconds,
log = log
log = log,
) {
override fun action(): SafeFuture<*> {
@@ -50,13 +50,13 @@ internal class BlobsFetchingTask(
}
private fun fetchBlobsOfSubmissionEvents(
submissionEvents: FinalizationAndDataEventsV3
submissionEvents: FinalizationAndDataEventsV3,
): SafeFuture<List<ByteArray>> {
return SafeFuture.collectAll(
submissionEvents.dataSubmittedEvents
.map {
transactionDetailsClient.getBlobVersionedHashesByTransactionHash(it.log.transactionHash)
}.stream()
}.stream(),
)
.thenCompose { blobsVersionedHashesByTransaction ->
blobsFetcher.fetchBlobsByHash(blobsVersionedHashesByTransaction.flatten())

View File

@@ -24,11 +24,11 @@ internal class SubmissionEventsFetchingTask(
private val submissionEventsQueue: ConcurrentLinkedQueue<FinalizationAndDataEventsV3>,
private val queueLimit: Int,
private val debugForceSyncStopBlockNumber: ULong?,
private val log: Logger = LogManager.getLogger(SubmissionEventsFetchingTask::class.java)
private val log: Logger = LogManager.getLogger(SubmissionEventsFetchingTask::class.java),
) : PeriodicPollingService(
vertx = vertx,
pollingIntervalMs = l1PollingInterval.inWholeMilliseconds,
log = log
log = log,
) {
val latestFetchedFinalization: AtomicReference<EthLogEvent<DataFinalizedV3>> = AtomicReference(null)
@@ -38,7 +38,7 @@ internal class SubmissionEventsFetchingTask(
) {
log.debug(
"Force stop fetching submission events from L1, reached debugForceSyncStopBlockNumber={}",
debugForceSyncStopBlockNumber
debugForceSyncStopBlockNumber,
)
return this.stop()
}
@@ -51,7 +51,7 @@ internal class SubmissionEventsFetchingTask(
// Queue is full, no need to fetch more
log.debug(
"skipping fetching submission events from L1, internal queue is full size={}",
submissionEventsQueue.size
submissionEventsQueue.size,
)
return SafeFuture.completedFuture(Unit)
}
@@ -74,21 +74,21 @@ internal class SubmissionEventsFetchingTask(
return if (latestFetchedFinalization.get() != null) {
log.trace(
"fetching submission events from L1 startBlockNumber={}",
latestFetchedFinalization.get().event.endBlockNumber + 1u
latestFetchedFinalization.get().event.endBlockNumber + 1u,
)
submissionEventsClient.findFinalizationAndDataSubmissionV3Events(
fromL1BlockNumber = latestFetchedFinalization.get().log.blockNumber.toBlockParameter(),
finalizationStartBlockNumber = latestFetchedFinalization.get().event.endBlockNumber + 1u
finalizationStartBlockNumber = latestFetchedFinalization.get().event.endBlockNumber + 1u,
)
} else {
log.trace(
"fetching submission events from L1 startBlockNumber={}",
l2StartBlockNumber
l2StartBlockNumber,
)
submissionEventsClient
.findFinalizationAndDataSubmissionV3EventsContainingL2BlockNumber(
fromL1BlockNumber = l1EarliestBlockWithFinalizationThatSupportRecovery,
l2BlockNumber = l2StartBlockNumber
l2BlockNumber = l2StartBlockNumber,
)
}
}

View File

@@ -28,7 +28,7 @@ import kotlin.time.Duration.Companion.seconds
*/
data class SubmissionEventsAndData<T>(
val submissionEvents: FinalizationAndDataEventsV3,
val data: List<T>
val data: List<T>,
)
class SubmissionsFetchingTask(
@@ -44,11 +44,11 @@ class SubmissionsFetchingTask(
private val compressedBlobsQueueLimit: Int,
private val targetDecompressedBlobsQueueLimit: Int,
private val debugForceSyncStopBlockNumber: ULong?,
private val log: Logger = LogManager.getLogger(SubmissionsFetchingTask::class.java)
private val log: Logger = LogManager.getLogger(SubmissionsFetchingTask::class.java),
) : PeriodicPollingService(
vertx = vertx,
pollingIntervalMs = l1PollingInterval.inWholeMilliseconds,
log = log
log = log,
) {
init {
require(submissionEventsQueueLimit >= 1) {
@@ -84,7 +84,7 @@ class SubmissionsFetchingTask(
l2StartBlockNumber = l2StartBlockNumberToFetchInclusive,
submissionEventsQueue = submissionEventsQueue,
queueLimit = submissionEventsQueueLimit,
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber,
)
private val blobFetchingTask = BlobsFetchingTask(
vertx = vertx,
@@ -93,7 +93,7 @@ class SubmissionsFetchingTask(
blobsFetcher = blobsFetcher,
transactionDetailsClient = transactionDetailsClient,
compressedBlobsQueue = compressedBlobsQueue,
compressedBlobsQueueLimit = compressedBlobsQueueLimit
compressedBlobsQueueLimit = compressedBlobsQueueLimit,
)
private val blobDecompressionTask = BlobDecompressionTask(
vertx = vertx,
@@ -101,7 +101,7 @@ class SubmissionsFetchingTask(
blobDecompressor = blobDecompressor,
rawBlobsQueue = compressedBlobsQueue,
decompressedBlocksQueue = decompressedBlocksQueue,
decompressedFinalizationQueueLimit = dynamicDecompressedBlobsQueueLimit::get
decompressedFinalizationQueueLimit = dynamicDecompressedBlobsQueueLimit::get,
)
@Synchronized
@@ -109,7 +109,7 @@ class SubmissionsFetchingTask(
return SafeFuture.allOf(
submissionEventsFetchingTask.start(),
blobFetchingTask.start(),
blobDecompressionTask.start()
blobDecompressionTask.start(),
).thenCompose { super.start() }
}
@@ -118,7 +118,7 @@ class SubmissionsFetchingTask(
return SafeFuture.allOf(
submissionEventsFetchingTask.stop(),
blobFetchingTask.stop(),
blobDecompressionTask.stop()
blobDecompressionTask.stop(),
).thenCompose { super.stop() }
}
@@ -136,7 +136,7 @@ class SubmissionsFetchingTask(
@Synchronized
fun pruneQueueForElementsUpToInclusive(
elHeadBlockNumber: ULong
elHeadBlockNumber: ULong,
) {
decompressedBlocksQueue.removeIf {
it.submissionEvents.dataFinalizedEvent.event.endBlockNumber <= elHeadBlockNumber

View File

@@ -29,7 +29,7 @@ class BlobDecompressorAndDeserializerV1Test {
private val blockStaticFields = BlockHeaderStaticFields(
coinbase = Address.ZERO.toArray(),
gasLimit = 30_000_000UL,
difficulty = 0UL
difficulty = 0UL,
)
private lateinit var decompressorToDomain: BlobDecompressorAndDeserializer
private lateinit var vertx: Vertx
@@ -39,7 +39,7 @@ class BlobDecompressorAndDeserializerV1Test {
vertx = Vertx.vertx()
compressor = GoBackedBlobCompressor.getInstance(
compressorVersion = BlobCompressorVersion.V1_2,
dataLimit = 124 * 1024
dataLimit = 124 * 1024,
)
val decompressor = GoNativeBlobDecompressorFactory.getInstance(BlobDecompressorVersion.V1_2_0)
decompressorToDomain = BlobDecompressorToDomainV1(decompressor, blockStaticFields, vertx)
@@ -57,7 +57,7 @@ class BlobDecompressorAndDeserializerV1Test {
}
private fun assertBlockCompressionAndDecompression(
blocksRLP: List<ByteArray>
blocksRLP: List<ByteArray>,
) {
val blocks = blocksRLP.map(RLP::decodeBlockWithMainnetFunctions)
val startingBlockNumber = blocks[0].header.number.toULong()
@@ -66,7 +66,7 @@ class BlobDecompressorAndDeserializerV1Test {
val recoveredBlocks = decompressorToDomain.decompress(
startBlockNumber = startingBlockNumber,
blobs = blobs
blobs = blobs,
).get()
assertThat(recoveredBlocks[0].header.blockNumber).isEqualTo(startingBlockNumber)
@@ -77,7 +77,7 @@ class BlobDecompressorAndDeserializerV1Test {
private fun assertBlockData(
uncompressed: BlockFromL1RecoveredData,
original: Block
original: Block,
) {
try {
assertThat(uncompressed.header.blockNumber).isEqualTo(original.header.number.toULong())
@@ -94,14 +94,14 @@ class BlobDecompressorAndDeserializerV1Test {
"uncompressed block does not match expected original: blockNumber: ${e.message} " +
"\n original =$original " +
"\n uncompressed=$uncompressed ",
e
e,
)
}
}
private fun assertTransactionData(
uncompressed: TransactionFromL1RecoveredData,
original: Transaction
original: Transaction,
) {
assertThat(uncompressed.type).isEqualTo(original.type.serializedType.toUByte())
assertThat(uncompressed.from).isEqualTo(original.sender.toArray())

View File

@@ -13,7 +13,7 @@ class StartingBlockCalculatorTest {
lookbackFetchingIntervals(
headBlockNumber = 50UL,
recoveryStartBlockNumber = null,
lookbackWindow = 10UL
lookbackWindow = 10UL,
).also { intervals ->
assertThat(intervals.l1Interval).isNull()
assertThat(intervals.elInterval).isEqualTo(BlockInterval(41UL, 50UL))
@@ -23,7 +23,7 @@ class StartingBlockCalculatorTest {
lookbackFetchingIntervals(
headBlockNumber = 5UL,
recoveryStartBlockNumber = null,
lookbackWindow = 10UL
lookbackWindow = 10UL,
).also { intervals ->
assertThat(intervals.l1Interval).isNull()
assertThat(intervals.elInterval).isEqualTo(BlockInterval(0UL, 5UL))
@@ -35,7 +35,7 @@ class StartingBlockCalculatorTest {
lookbackFetchingIntervals(
headBlockNumber = 50UL,
recoveryStartBlockNumber = 51UL,
lookbackWindow = 10UL
lookbackWindow = 10UL,
).also { intervals ->
assertThat(intervals.l1Interval).isNull()
assertThat(intervals.elInterval).isEqualTo(BlockInterval(41UL, 50UL))
@@ -47,7 +47,7 @@ class StartingBlockCalculatorTest {
lookbackFetchingIntervals(
headBlockNumber = 0UL,
recoveryStartBlockNumber = 1UL,
lookbackWindow = 10UL
lookbackWindow = 10UL,
).also { intervals ->
assertThat(intervals.l1Interval).isNull()
assertThat(intervals.elInterval).isEqualTo(BlockInterval(0UL, 0UL))
@@ -59,7 +59,7 @@ class StartingBlockCalculatorTest {
lookbackFetchingIntervals(
headBlockNumber = 50UL,
recoveryStartBlockNumber = 10UL,
lookbackWindow = 10UL
lookbackWindow = 10UL,
).also { intervals ->
assertThat(intervals.l1Interval).isEqualTo(BlockInterval(41UL, 50UL))
assertThat(intervals.elInterval).isNull()
@@ -71,7 +71,7 @@ class StartingBlockCalculatorTest {
lookbackFetchingIntervals(
headBlockNumber = 50UL,
recoveryStartBlockNumber = 45UL,
lookbackWindow = 10UL
lookbackWindow = 10UL,
).also { intervals ->
assertThat(intervals.l1Interval).isEqualTo(BlockInterval(45UL, 50UL))
assertThat(intervals.elInterval).isEqualTo(BlockInterval(41UL, 44UL))
@@ -86,7 +86,7 @@ class StartingBlockCalculatorTest {
startBlockToFetchFromL1(
headBlockNumber = 500UL,
recoveryStartBlockNumber = null,
lookbackWindow = 256UL
lookbackWindow = 256UL,
).also { result ->
// Then
assertThat(result).isEqualTo(501UL)
@@ -95,7 +95,7 @@ class StartingBlockCalculatorTest {
startBlockToFetchFromL1(
headBlockNumber = 200UL,
recoveryStartBlockNumber = null,
lookbackWindow = 256UL
lookbackWindow = 256UL,
).also { result ->
// Then
assertThat(result).isEqualTo(201UL)
@@ -107,7 +107,7 @@ class StartingBlockCalculatorTest {
startBlockToFetchFromL1(
headBlockNumber = 500UL,
recoveryStartBlockNumber = 250UL,
lookbackWindow = 100UL
lookbackWindow = 100UL,
).also { result ->
// Then
assertThat(result).isEqualTo(400UL)
@@ -119,7 +119,7 @@ class StartingBlockCalculatorTest {
startBlockToFetchFromL1(
headBlockNumber = 500UL,
recoveryStartBlockNumber = 450UL,
lookbackWindow = 100UL
lookbackWindow = 100UL,
).also { result ->
// Then
assertThat(result).isEqualTo(450UL)
@@ -129,7 +129,7 @@ class StartingBlockCalculatorTest {
startBlockToFetchFromL1(
headBlockNumber = 50UL,
recoveryStartBlockNumber = 45UL,
lookbackWindow = 100UL
lookbackWindow = 100UL,
).also { result ->
// Then
assertThat(result).isEqualTo(45UL)

View File

@@ -21,7 +21,7 @@ class ExecutionLayerInProcessClient(
private val blockchainService: BlockchainService,
private val stateRecoveryModeManager: RecoveryModeManager,
private val stateRecoveryStatusPersistence: RecoveryStatusPersistence,
private val blockImporter: BlockImporter
private val blockImporter: BlockImporter,
) : ExecutionLayerClient {
companion object {
fun create(
@@ -29,7 +29,7 @@ class ExecutionLayerInProcessClient(
simulatorService: BlockSimulationService,
synchronizationService: SynchronizationService,
stateRecoveryModeManager: RecoveryModeManager,
stateRecoveryStatusPersistence: RecoveryStatusPersistence
stateRecoveryStatusPersistence: RecoveryStatusPersistence,
): ExecutionLayerInProcessClient {
return ExecutionLayerInProcessClient(
blockchainService = blockchainService,
@@ -38,8 +38,8 @@ class ExecutionLayerInProcessClient(
blockImporter = BlockImporter(
blockchainService = blockchainService,
simulatorService = simulatorService,
synchronizationService = synchronizationService
)
synchronizationService = synchronizationService,
),
)
}
}
@@ -71,8 +71,8 @@ class ExecutionLayerInProcessClient(
SafeFuture.completedFuture(
BlockNumberAndHash(
it.number.toULong(),
it.blockHash.toArray()
)
it.blockHash.toArray(),
),
)
}
?: SafeFuture.failedFuture(IllegalArgumentException("Block not found for parameter: $blockParameter"))
@@ -91,8 +91,8 @@ class ExecutionLayerInProcessClient(
.completedFuture(
StateRecoveryStatus(
headBlockNumber = stateRecoveryModeManager.headBlockNumber,
stateRecoverStartBlockNumber = stateRecoveryModeManager.targetBlockNumber
)
stateRecoverStartBlockNumber = stateRecoveryModeManager.targetBlockNumber,
),
)
}
@@ -102,8 +102,8 @@ class ExecutionLayerInProcessClient(
return SafeFuture.completedFuture(
StateRecoveryStatus(
headBlockNumber = stateRecoveryModeManager.headBlockNumber,
stateRecoverStartBlockNumber = stateRecoveryStatusPersistence.getRecoveryStartBlockNumber()
)
stateRecoverStartBlockNumber = stateRecoveryStatusPersistence.getRecoveryStartBlockNumber(),
),
)
}
@@ -113,7 +113,7 @@ class ExecutionLayerInProcessClient(
} else {
log.debug(
"importing blocks from blob: blocks={}",
CommonDomainFunctions.blockIntervalString(blocks.first().header.blockNumber, blocks.last().header.blockNumber)
CommonDomainFunctions.blockIntervalString(blocks.first().header.blockNumber, blocks.last().header.blockNumber),
)
}
}

View File

@@ -37,7 +37,7 @@ fun createAppAllInProcess(
blobScanRequestRetryConfig: RetryConfig,
blobscanRequestRatelimitBackoffDelay: Duration?,
blockHeaderStaticFields: BlockHeaderStaticFields,
appConfig: StateRecoveryApp.Config
appConfig: StateRecoveryApp.Config,
): StateRecoveryApp {
return createAppClients(
vertx = vertx,
@@ -49,7 +49,7 @@ fun createAppAllInProcess(
l1RequestRetryConfig = l1RequestRetryConfig,
blobScanEndpoint = blobScanEndpoint,
blobScanRequestRetryConfig = blobScanRequestRetryConfig,
blobscanRequestRateLimitBackoffDelay = blobscanRequestRatelimitBackoffDelay
blobscanRequestRateLimitBackoffDelay = blobscanRequestRatelimitBackoffDelay,
).let { clients ->
val app = StateRecoveryApp(
vertx = vertx,
@@ -60,7 +60,7 @@ fun createAppAllInProcess(
stateManagerClient = clients.stateManagerClient,
transactionDetailsClient = clients.transactionDetailsClient,
blockHeaderStaticFields = blockHeaderStaticFields,
config = appConfig
config = appConfig,
)
app
}
@@ -71,7 +71,7 @@ data class AppClients(
val ethLogsSearcher: EthLogsSearcherImpl,
val blobScanClient: BlobScanClient,
val stateManagerClient: StateManagerClientV1,
val transactionDetailsClient: TransactionDetailsClient
val transactionDetailsClient: TransactionDetailsClient,
)
fun RetryConfig.toRequestRetryConfig(): RequestRetryConfig {
@@ -79,7 +79,7 @@ fun RetryConfig.toRequestRetryConfig(): RequestRetryConfig {
maxRetries = this.maxRetries,
timeout = this.timeout,
backoffDelay = this.backoffDelay,
failuresWarningThreshold = this.failuresWarningThreshold
failuresWarningThreshold = this.failuresWarningThreshold,
)
}
@@ -95,14 +95,14 @@ fun createAppClients(
stateManagerClientEndpoint: URI,
blobscanRequestRateLimitBackoffDelay: Duration? = null,
stateManagerRequestRetry: RetryConfig = RetryConfig(backoffDelay = 1.seconds),
zkStateManagerVersion: String = "2.3.0"
zkStateManagerVersion: String = "2.3.0",
): AppClients {
val lineaContractClient = Web3JLineaRollupSmartContractClientReadOnly(
contractAddress = smartContractAddress,
web3j = createWeb3jHttpClient(
rpcUrl = l1RpcEndpoint.toString(),
log = LogManager.getLogger("linea.plugin.staterecovery.clients.l1.smart-contract")
)
log = LogManager.getLogger("linea.plugin.staterecovery.clients.l1.smart-contract"),
),
)
val ethLogsSearcher = run {
val log = LogManager.getLogger("linea.plugin.staterecovery.clients.l1.logs-searcher")
@@ -110,15 +110,15 @@ fun createAppClients(
vertx = vertx,
rpcUrl = l1RpcEndpoint.toString(),
requestRetryConfig = l1RequestRetryConfig,
log = log
log = log,
)
EthLogsSearcherImpl(
vertx = vertx,
ethApiClient = web3jEthApiClient,
config = EthLogsSearcherImpl.Config(
loopSuccessBackoffDelay = l1SuccessBackoffDelay
loopSuccessBackoffDelay = l1SuccessBackoffDelay,
),
log = log
log = log,
)
}
val blobScanClient = BlobScanClient.create(
@@ -126,7 +126,7 @@ fun createAppClients(
endpoint = blobScanEndpoint,
requestRetryConfig = blobScanRequestRetryConfig,
logger = LogManager.getLogger("linea.plugin.staterecovery.clients.l1.blob-scan"),
rateLimitBackoffDelay = blobscanRequestRateLimitBackoffDelay
rateLimitBackoffDelay = blobscanRequestRateLimitBackoffDelay,
)
val jsonRpcClientFactory = VertxHttpJsonRpcClientFactory(vertx, MicrometerMetricsFacade(meterRegistry))
val stateManagerClient: StateManagerClientV1 = StateManagerV1JsonRpcClient.create(
@@ -135,19 +135,19 @@ fun createAppClients(
maxInflightRequestsPerClient = 10u,
requestRetry = stateManagerRequestRetry.toRequestRetryConfig(),
zkStateManagerVersion = zkStateManagerVersion,
logger = LogManager.getLogger("linea.plugin.staterecovery.clients.state-manager")
logger = LogManager.getLogger("linea.plugin.staterecovery.clients.state-manager"),
)
val transactionDetailsClient: TransactionDetailsClient = VertxTransactionDetailsClient.create(
jsonRpcClientFactory = jsonRpcClientFactory,
endpoint = l1RpcEndpoint,
retryConfig = l1RequestRetryConfig.toRequestRetryConfig(),
logger = LogManager.getLogger("linea.plugin.staterecovery.clients.l1.transaction-details")
logger = LogManager.getLogger("linea.plugin.staterecovery.clients.l1.transaction-details"),
)
return AppClients(
lineaContractClient = lineaContractClient,
ethLogsSearcher = ethLogsSearcher,
blobScanClient = blobScanClient,
stateManagerClient = stateManagerClient,
transactionDetailsClient = transactionDetailsClient
transactionDetailsClient = transactionDetailsClient,
)
}

View File

@@ -6,7 +6,7 @@ import org.hyperledger.besu.plugin.data.BlockHeader
data class BlockContextData(
private val blockHeader: BlockHeader,
private val blockBody: BlockBody
private val blockBody: BlockBody,
) : BlockContext {
override fun getBlockHeader(): BlockHeader = blockHeader
override fun getBlockBody(): BlockBody = blockBody

View File

@@ -13,7 +13,7 @@ import java.util.concurrent.ConcurrentHashMap
class BlockHashLookupWithRecoverySupport(
val lookbackWindow: ULong,
private val log: Logger = LogManager.getLogger(BlockHashLookupWithRecoverySupport::class.java)
private val log: Logger = LogManager.getLogger(BlockHashLookupWithRecoverySupport::class.java),
) : BlockHashLookup {
private val lookbackHashesMap = ConcurrentHashMap<ULong, ByteArray>()

View File

@@ -22,8 +22,8 @@ class BlockImporter(
private val simulatorService: BlockSimulationService,
private val synchronizationService: SynchronizationService,
private val blockHashLookup: BlockHashLookupWithRecoverySupport = BlockHashLookupWithRecoverySupport(
lookbackWindow = 256UL
)
lookbackWindow = 256UL,
),
) {
private val log = LogManager.getLogger(BlockImporter::class.java)
private val chainId = blockchainService.chainId.orElseThrow().toULong()
@@ -40,16 +40,16 @@ class BlockImporter(
}
private fun executeBlockWithTransactionsWithoutSignature(
block: BlockFromL1RecoveredData
block: BlockFromL1RecoveredData,
): PluginBlockSimulationResult {
log.trace(
"simulating import block={} blockHash={}",
block.header.blockNumber,
block.header.blockHash.encodeHex()
block.header.blockHash.encodeHex(),
)
val transactions = TransactionMapper.mapToBesu(
block.transactions,
chainId
chainId,
)
val parentBlockNumber = block.header.blockNumber.toLong() - 1
@@ -58,13 +58,13 @@ class BlockImporter(
parentBlockNumber,
transactions,
createOverrides(block, blockHashLookup::getHash),
StateOverrideMap()
StateOverrideMap(),
)
log.trace(
" import simulation result: block={} blockHeader={}",
executedBlockResult.blockHeader.number,
executedBlockResult.blockHeader
executedBlockResult.blockHeader,
)
return executedBlockResult
}
@@ -73,7 +73,7 @@ class BlockImporter(
log.trace(
"calling simulateAndPersistWorldState block={} blockHeader={}",
context.blockHeader.number,
context.blockHeader
context.blockHeader,
)
val parentBlockNumber = context.blockHeader.number - 1
val importedBlockResult =
@@ -81,12 +81,12 @@ class BlockImporter(
parentBlockNumber,
context.blockBody.transactions,
createOverrides(context.blockHeader, blockHashLookup::getHash),
StateOverrideMap()
StateOverrideMap(),
)
log.trace(
"simulateAndPersistWorldState result: block={} blockHeader={}",
context.blockHeader.number,
importedBlockResult.blockHeader
importedBlockResult.blockHeader,
)
storeAndSetHead(importedBlockResult)
return importedBlockResult
@@ -95,12 +95,12 @@ class BlockImporter(
private fun storeAndSetHead(block: PluginBlockSimulationResult) {
log.debug(
"storeAndSetHead result: blockHeader={}",
block.blockHeader
block.blockHeader,
)
blockchainService.storeBlock(
block.blockHeader,
block.blockBody,
block.receipts
block.receipts,
)
synchronizationService.setHeadUnsafe(block.blockHeader, block.blockBody)
}
@@ -108,7 +108,7 @@ class BlockImporter(
companion object {
fun createOverrides(
blockFromBlob: BlockFromL1RecoveredData,
blockHashLookup: (Long) -> Hash
blockHashLookup: (Long) -> Hash,
): BlockOverrides {
return BlockOverrides.builder()
.blockHash(Hash.wrap(Bytes32.wrap(blockFromBlob.header.blockHash)))
@@ -124,7 +124,7 @@ class BlockImporter(
fun createOverrides(
blockHeader: BlockHeader,
blockHashLookup: (Long) -> Hash
blockHashLookup: (Long) -> Hash,
): BlockOverrides {
return BlockOverrides.builder()
.feeRecipient(blockHeader.coinbase)

View File

@@ -36,7 +36,7 @@ open class LineaStateRecoveryPlugin : BesuPlugin {
warningExceptionTime = 5.minutes,
jvmMetricsEnabled = false,
prometheusMetricsEnabled = false,
preferNativeTransport = false
preferNativeTransport = false,
)
private val cliOptions = PluginCliOptions()
private lateinit var serviceManager: ServiceManager
@@ -59,18 +59,18 @@ open class LineaStateRecoveryPlugin : BesuPlugin {
val blockHeaderStaticFields = BlockHeaderStaticFields(
coinbase = config.lineaSequencerBeneficiaryAddress.toArray(),
gasLimit = config.lineaBlockGasLimit,
difficulty = config.lineaBlockDifficulty
difficulty = config.lineaBlockDifficulty,
)
this.recoveryStatusPersistence = FileBasedRecoveryStatusPersistence(
serviceManager.getServiceOrThrow(BesuConfiguration::class.java)
.dataPath
.resolve("plugin-staterecovery-status.json")
.resolve("plugin-staterecovery-status.json"),
)
log.info(
"starting: config={} blockHeaderStaticFields={} previousRecoveryStartBlockNumber={}",
config,
blockHeaderStaticFields,
this.recoveryStatusPersistence.getRecoveryStartBlockNumber()
this.recoveryStatusPersistence.getRecoveryStartBlockNumber(),
)
val synchronizationService = serviceManager.getServiceOrThrow(SynchronizationService::class.java)
@@ -80,7 +80,7 @@ open class LineaStateRecoveryPlugin : BesuPlugin {
recoveryStatePersistence = this.recoveryStatusPersistence,
synchronizationService = synchronizationService,
headBlockNumber = blockchainService.chainHeadHeader.number.toULong(),
debugForceSyncStopBlockNumber = config.debugForceSyncStopBlockNumber
debugForceSyncStopBlockNumber = config.debugForceSyncStopBlockNumber,
)
val simulatorService = serviceManager.getServiceOrThrow(BlockSimulationService::class.java)
val executionLayerClient = ExecutionLayerInProcessClient.create(
@@ -88,7 +88,7 @@ open class LineaStateRecoveryPlugin : BesuPlugin {
stateRecoveryModeManager = this.recoveryModeManager,
stateRecoveryStatusPersistence = this.recoveryStatusPersistence,
simulatorService = simulatorService,
synchronizationService = synchronizationService
synchronizationService = synchronizationService,
)
this.stateRecoverApp = run {
@@ -112,8 +112,8 @@ open class LineaStateRecoveryPlugin : BesuPlugin {
l1LatestSearchBlock = config.l1HighestSearchBlock,
l1PollingInterval = config.l1PollingInterval,
overridingRecoveryStartBlockNumber = config.overridingRecoveryStartBlockNumber,
debugForceSyncStopBlockNumber = config.debugForceSyncStopBlockNumber
)
debugForceSyncStopBlockNumber = config.debugForceSyncStopBlockNumber,
),
)
}
// add recoverty mode manager as listener to block added events
@@ -129,7 +129,7 @@ open class LineaStateRecoveryPlugin : BesuPlugin {
this.recoveryModeManager.enableRecoveryModeIfNecessary()
log.info(
"started: recoveryStartBlockNumber={}",
this.recoveryStatusPersistence.getRecoveryStartBlockNumber()
this.recoveryStatusPersistence.getRecoveryStartBlockNumber(),
)
this.stateRecoverApp.start().get()
}

View File

@@ -25,7 +25,7 @@ data class PluginConfig(
val blobscanRequestRatelimitBackoffDelay: kotlin.time.Duration?,
val shomeiEndpoint: URI,
val overridingRecoveryStartBlockNumber: ULong? = null,
val debugForceSyncStopBlockNumber: ULong? = null
val debugForceSyncStopBlockNumber: ULong? = null,
) {
init {
require(l1PollingInterval >= 1.milliseconds) { "Polling interval=$l1PollingInterval must be greater than 1ms." }
@@ -43,7 +43,7 @@ class PluginCliOptions {
description = ["Linea sequencer beneficiary address"],
required = true,
converter = [AddressConverter::class],
defaultValue = "\${env:LINEA_SEQUENCER_BENEFICIARY_ADDRESS}"
defaultValue = "\${env:LINEA_SEQUENCER_BENEFICIARY_ADDRESS}",
)
lateinit var lineaSequencerBeneficiaryAddress: Address
@@ -51,7 +51,7 @@ class PluginCliOptions {
names = ["--$cliOptionsPrefix-linea-block-gas-limit"],
description = ["Linea Block gas limit. Default 2B (2_000_000_000)"],
required = false,
defaultValue = "\${env:LINEA_BLOCK_GAS_LIMIT}"
defaultValue = "\${env:LINEA_BLOCK_GAS_LIMIT}",
)
var lineaBlockGasLimit: Long = 2_000_000_000L
@@ -59,7 +59,7 @@ class PluginCliOptions {
names = ["--$cliOptionsPrefix-linea-block-difficulty"],
description = ["Linea Block difficulty. Default 2"],
required = false,
defaultValue = "\${env:LINEA_BLOCK_DIFFICULTY}"
defaultValue = "\${env:LINEA_BLOCK_DIFFICULTY}",
)
var lineaBlockDifficulty: Long = 2
@@ -68,14 +68,14 @@ class PluginCliOptions {
description = ["L1 smart contract address"],
required = true,
converter = [AddressConverter::class],
defaultValue = "\${env:L1_ROLLUP_CONTRACT_ADDRESS}"
defaultValue = "\${env:L1_ROLLUP_CONTRACT_ADDRESS}",
)
lateinit var l1SmartContractAddress: Address
@CommandLine.Option(
names = ["--$cliOptionsPrefix-l1-endpoint"],
description = ["L1 RPC endpoint"],
required = true
required = true,
)
lateinit var l1RpcEndpoint: URI
@@ -83,7 +83,7 @@ class PluginCliOptions {
names = ["--$cliOptionsPrefix-l1-polling-interval"],
defaultValue = "PT12S",
description = ["L1 polling interval for new finalized blobs"],
required = false
required = false,
)
var l1PollingInterval: java.time.Duration = java.time.Duration.ofSeconds(12)
@@ -91,7 +91,7 @@ class PluginCliOptions {
names = ["--$cliOptionsPrefix-l1-get-logs-chunk-size"],
defaultValue = "10000",
description = ["Chuck size (fromBlock..toBlock) for eth_getLogs initial search loop"],
required = false
required = false,
)
var l1GetLogsChunkSize: Int = 10_000
@@ -100,10 +100,10 @@ class PluginCliOptions {
defaultValue = "EARLIEST",
description = [
"Earliest L1 Block to search for new finalizations on startup.",
"Optional, if defined it shall match L1 block with 1st finalization that supports recovery."
"Optional, if defined it shall match L1 block with 1st finalization that supports recovery.",
],
converter = [BlockParameterConverter::class],
required = false
required = false,
)
var l1EarliestSearchBlock: BlockParameter = BlockParameter.Tag.EARLIEST
@@ -112,10 +112,10 @@ class PluginCliOptions {
defaultValue = "FINALIZED",
description = [
"Highest L1 Block to search for new finalizations.",
"Finalized is highly recommended, otherwise if state is reverted it may require a full resync. "
"Finalized is highly recommended, otherwise if state is reverted it may require a full resync. ",
],
converter = [BlockParameterConverter::class],
required = false
required = false,
)
var l1HighestSearchBlock: BlockParameter = BlockParameter.Tag.FINALIZED
@@ -123,9 +123,9 @@ class PluginCliOptions {
names = ["--$cliOptionsPrefix-l1-success-backoff-delay"],
description = [
"L1 RPC api retry backoff delay, default none. ",
"Request will fire as soon as previous response is received"
"Request will fire as soon as previous response is received",
],
required = false
required = false,
)
var l1RequestSuccessBackoffDelay: java.time.Duration? = null
@@ -133,7 +133,7 @@ class PluginCliOptions {
names = ["--$cliOptionsPrefix-l1-retry-backoff-delay"],
defaultValue = "PT1S",
description = ["L1 RPC api retry backoff delay, default 1s"],
required = false
required = false,
)
var l1RequestRetryBackoffDelay: java.time.Duration = java.time.Duration.ofSeconds(1)
@@ -141,9 +141,9 @@ class PluginCliOptions {
names = ["--$cliOptionsPrefix-l1-retry-timeout"],
description = [
"L1 RPC api stop retrying as soon as timeout has elapsed or limit is reached",
"default will retry indefinitely"
"default will retry indefinitely",
],
required = false
required = false,
)
var l1RequestRetryTimeout: java.time.Duration? = null
@@ -151,37 +151,37 @@ class PluginCliOptions {
names = ["--$cliOptionsPrefix-l1-retry-limit"],
description = [
"L1 RPC api stop retrying when limit is reached or timeout has elapsed",
"default will retry indefinitely"
"default will retry indefinitely",
],
required = false
required = false,
)
var l1RequestRetryLimit: Int? = null
@CommandLine.Option(
names = ["--$cliOptionsPrefix-shomei-endpoint"],
description = ["shomei (state manager) endpoint"],
required = true
required = true,
)
lateinit var shomeiEndpoint: URI
@CommandLine.Option(
names = ["--$cliOptionsPrefix-blobscan-endpoint"],
description = ["blobscan api endpoint"],
required = true
required = true,
)
lateinit var blobscanEndpoint: URI
@CommandLine.Option(
names = ["--$cliOptionsPrefix-blobscan-retry-backoff-delay"],
description = ["blobscan api retry backoff delay, default 1s"],
required = false
required = false,
)
var blobscanRequestRetryBackoffDelay: java.time.Duration = java.time.Duration.ofSeconds(1)
@CommandLine.Option(
names = ["--$cliOptionsPrefix-blobscan-ratelimit-backoff-delay"],
description = ["blobscan api retry ratelimit backoff delay, default is disabled"],
required = false
required = false,
)
var blobscanRequestRatelimitBackoffDelay: java.time.Duration? = null
@@ -189,9 +189,9 @@ class PluginCliOptions {
names = ["--$cliOptionsPrefix-blobscan-retry-timeout"],
description = [
"Blobscan api stop retrying as soon as timeout has elapsed or limit is reached.",
"default will retry indefinitely"
"default will retry indefinitely",
],
required = false
required = false,
)
var blobscanRequestRetryTimeout: java.time.Duration? = null
@@ -199,9 +199,9 @@ class PluginCliOptions {
names = ["--$cliOptionsPrefix-blobscan-retry-limit"],
description = [
"Blobscan api stop retrying when limit is reached or timeout has elapsed",
"default will retry indefinitely"
"default will retry indefinitely",
],
required = false
required = false,
)
var blobscanRequestRetryLimit: Int? = null
@@ -209,10 +209,10 @@ class PluginCliOptions {
names = ["--$cliOptionsPrefix-overriding-recovery-start-block-number"],
description = [
"Tries to force the recovery start block number to the given value. " +
"This is mean for testing purposes, not production. Must be greater than or equal to 1."
"This is mean for testing purposes, not production. Must be greater than or equal to 1.",
],
defaultValue = "\${env:STATERECOVERY_OVERRIDE_START_BLOCK_NUMBER}",
required = false
required = false,
)
var overridingRecoveryStartBlockNumber: Long? = null
@@ -220,10 +220,10 @@ class PluginCliOptions {
names = ["--$cliOptionsPrefix-debug-force-sync-stop-block-number"],
description = [
"Forces Besu to stop syncing at the given block number. " +
"This is mean for testing purposes, not production. Must be greater than or equal to 1."
"This is mean for testing purposes, not production. Must be greater than or equal to 1.",
],
defaultValue = "\${env:STATERECOVERY_DEBUG_FORCE_STOP_SYNC_BLOCK_NUMBER}",
required = false
required = false,
)
var debugForceSyncStopBlockNumber: Long? = null
@@ -252,25 +252,25 @@ class PluginCliOptions {
l1RequestRetryConfig = RetryConfig(
backoffDelay = l1RequestRetryBackoffDelay.toKotlinDuration(),
timeout = l1RequestRetryTimeout?.toKotlinDuration(),
maxRetries = l1RequestRetryLimit?.toUInt()
maxRetries = l1RequestRetryLimit?.toUInt(),
),
blobscanEndpoint = blobscanEndpoint,
blobScanRequestRetryConfig = RetryConfig(
backoffDelay = blobscanRequestRetryBackoffDelay.toKotlinDuration(),
timeout = blobscanRequestRetryTimeout?.toKotlinDuration(),
maxRetries = blobscanRequestRetryLimit?.toUInt()
maxRetries = blobscanRequestRetryLimit?.toUInt(),
),
blobscanRequestRatelimitBackoffDelay = blobscanRequestRatelimitBackoffDelay?.toKotlinDuration(),
shomeiEndpoint = shomeiEndpoint,
overridingRecoveryStartBlockNumber = overridingRecoveryStartBlockNumber?.toULong(),
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber?.toULong()
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber?.toULong(),
)
}
class AddressConverter : CommandLine.ITypeConverter<Address> {
override fun convert(value: String): Address {
return Address.fromHexStringStrict(value) ?: throw CommandLine.TypeConversionException(
"Invalid address: $value"
"Invalid address: $value",
)
}
}

View File

@@ -16,7 +16,7 @@ class RecoveryModeManager(
private val miningService: MiningService,
private val recoveryStatePersistence: RecoveryStatusPersistence,
private val debugForceSyncStopBlockNumber: ULong? = null,
headBlockNumber: ULong
headBlockNumber: ULong,
) :
BesuEvents.BlockAddedListener {
private val log: Logger = LogManager.getLogger(RecoveryModeManager::class.java.name)
@@ -37,7 +37,7 @@ class RecoveryModeManager(
log.info(
"enabling recovery mode immediately at blockNumber={} recoveryTargetBlockNumber={}",
headBlockNumber,
targetBlockNumber
targetBlockNumber,
)
switchToRecoveryMode()
}
@@ -56,14 +56,14 @@ class RecoveryModeManager(
log.info(
"Stopping synchronization services at block={} recoveryTargetBlockNumber={} was reached",
headBlockNumber,
targetBlockNumber
targetBlockNumber,
)
switchToRecoveryMode()
} else if (debugForceSyncStopBlockNumber != null && headBlockNumber >= debugForceSyncStopBlockNumber) {
log.info(
"Stopping synchronization services at block={} debugForceSyncStopBlockNumber={}",
headBlockNumber,
debugForceSyncStopBlockNumber
debugForceSyncStopBlockNumber,
)
stopBesuServices()
}
@@ -71,7 +71,7 @@ class RecoveryModeManager(
private fun hasReachedTargetBlock(
headBlockNumber: ULong = this.headBlockNumber,
targetBlockNumber: ULong? = this.targetBlockNumber
targetBlockNumber: ULong? = this.targetBlockNumber,
): Boolean {
return (headBlockNumber + 1u) >= (targetBlockNumber ?: ULong.MAX_VALUE)
}

View File

@@ -25,7 +25,7 @@ object TransactionMapper {
*/
fun mapToBesu(
transaction: TransactionFromL1RecoveredData,
chainId: ULong
chainId: ULong,
): Transaction {
val builder = Transaction.builder()
builder
@@ -48,13 +48,13 @@ object TransactionMapper {
}
private fun mapAccessListEntries(
accessList: List<AccessTuple>?
accessList: List<AccessTuple>?,
): List<AccessListEntry>? {
return accessList
?.map { accessTupleParameter ->
AccessListEntry.createAccessListEntry(
accessTupleParameter.address.toBesuAddress(),
accessTupleParameter.storageKeys.map { it.encodeHex() }
accessTupleParameter.storageKeys.map { it.encodeHex() },
)
}
}
@@ -69,7 +69,7 @@ object TransactionMapper {
*/
fun mapToBesu(
transactions: List<TransactionFromL1RecoveredData>,
defaultChainId: ULong
defaultChainId: ULong,
): List<Transaction> {
return transactions.map { tx -> mapToBesu(tx, defaultChainId) }
}

View File

@@ -15,16 +15,16 @@ class BlockHashLookupWithRecoverySupportTest {
lookback.addLookbackHashes(
mapOf(
1UL to hashOf(1UL),
2UL to hashOf(3UL)
)
2UL to hashOf(3UL),
),
)
assertThatThrownBy {
lookback.addLookbackHashes(
mapOf(
1UL to hashOf(1UL),
3UL to hashOf(3UL)
)
3UL to hashOf(3UL),
),
)
}
.isInstanceOf(IllegalArgumentException::class.java)
@@ -34,7 +34,7 @@ class BlockHashLookupWithRecoverySupportTest {
@Test
fun `addHeadBlockHash should update and prune the lookback hashes outside the lookback window`() {
val lookback = BlockHashLookupWithRecoverySupport(
lookbackWindow = 3UL
lookbackWindow = 3UL,
)
lookback.addHeadBlockHash(0UL, hashOf(123UL))

View File

@@ -24,11 +24,11 @@ class StaticVertxHttpRequestRateLimiter(
.div(5)
.coerceAtLeast(1.milliseconds),
private val requestLogFormatter: VertxHttpLoggingFormatter,
private val logger: Logger = LogManager.getLogger(StaticVertxHttpRequestRateLimiter::class.java)
private val logger: Logger = LogManager.getLogger(StaticVertxHttpRequestRateLimiter::class.java),
) : VertxHttpRequestSender {
private data class RequestAndFutureResponse(
val request: HttpRequest<Buffer>,
val future: SafeFuture<HttpResponse<Buffer>>
val future: SafeFuture<HttpResponse<Buffer>>,
)
private val rateLimitPerSecond = 1.seconds.div(rateLimitBackoffDelay).toInt()
@@ -54,7 +54,7 @@ class StaticVertxHttpRequestRateLimiter(
rateLimitPerSecond,
requestQueue.size,
rateLimitBackoffDelay - elapsedTimeSinceLastRequest,
requestLogFormatter.toLogString(requestQueue.peek().request)
requestLogFormatter.toLogString(requestQueue.peek().request),
)
return
}
@@ -93,7 +93,7 @@ class StaticVertxHttpRequestRateLimiter(
rateLimitPerSecond,
requestQueue.size,
rateLimitBackoffDelay - lastRequestFiredTime.elapsedNow(),
requestLogFormatter.toLogString(request)
requestLogFormatter.toLogString(request),
)
requestQueue.add(req)

View File

@@ -9,7 +9,7 @@ interface VertxHttpLoggingFormatter {
fun toLogString(
request: HttpRequest<Buffer>,
response: HttpResponse<Buffer>? = null,
failureCause: Throwable? = null
failureCause: Throwable? = null,
): String
}
@@ -22,14 +22,14 @@ fun HttpRequest<*>.fullUri(): String {
scheme,
this.host(),
this.port(),
path
path,
)
}
class VertxRestLoggingFormatter(
private val includeFullUri: Boolean = false,
private val uriTransformer: (String) -> String = { it },
private val responseLogMaxSize: UInt? = null
private val responseLogMaxSize: UInt? = null,
) : VertxHttpLoggingFormatter {
fun HttpRequest<*>.uriToLog(): String {
return if (includeFullUri) {
@@ -46,14 +46,14 @@ class VertxRestLoggingFormatter(
override fun toLogString(
request: HttpRequest<Buffer>,
response: HttpResponse<Buffer>?,
failureCause: Throwable?
failureCause: Throwable?,
): String {
return if (failureCause != null) {
String.format(
"<-- %s %s %s",
request.method(),
uriTransformer.invoke(request.uriToLog()),
failureCause.message?.let { errorMsg -> "error=$errorMsg" } ?: ""
failureCause.message?.let { errorMsg -> "error=$errorMsg" } ?: "",
)
} else {
val responseToLog = response?.bodyAsString()?.let { bodyStr ->
@@ -68,7 +68,7 @@ class VertxRestLoggingFormatter(
request.method(),
uriTransformer.invoke(request.uriToLog()),
response?.statusCode() ?: "",
responseToLog
responseToLog,
)
}
}

View File

@@ -16,7 +16,7 @@ interface VertxHttpRequestSender {
* Handy to avoid creating anonymous classes.
*/
class SimpleVertxHttpRequestSender(
private val requestLogger: VertxRequestLogger
private val requestLogger: VertxRequestLogger,
) : VertxHttpRequestSender {
override fun makeRequest(request: HttpRequest<Buffer>): SafeFuture<HttpResponse<Buffer>> {
requestLogger.logRequest(request)

View File

@@ -13,7 +13,7 @@ object VertxHttpRequestSenderFactory {
rateLimitBackoffDelay: Duration? = null,
retryableErrorCodes: Set<Int> = setOf(429, 503, 504),
logFormatter: VertxHttpLoggingFormatter,
baseRequestSender: VertxHttpRequestSender
baseRequestSender: VertxHttpRequestSender,
): VertxHttpRequestSender {
val rateLimitedSender = rateLimitBackoffDelay
?.let {
@@ -21,7 +21,7 @@ object VertxHttpRequestSenderFactory {
vertx = vertx,
requestSender = baseRequestSender,
rateLimitBackoffDelay = rateLimitBackoffDelay,
requestLogFormatter = logFormatter
requestLogFormatter = logFormatter,
)
} ?: baseRequestSender
val sender = requestRetryConfig
@@ -30,7 +30,7 @@ object VertxHttpRequestSenderFactory {
vertx = vertx,
requestSender = rateLimitedSender,
requestRetryConfig = requestRetryConfig,
retryableErrorCodes = retryableErrorCodes
retryableErrorCodes = retryableErrorCodes,
)
} ?: rateLimitedSender
@@ -45,13 +45,13 @@ object VertxHttpRequestSenderFactory {
requestResponseLogLevel: Level = Level.TRACE,
failuresLogLevel: Level = Level.DEBUG,
retryableErrorCodes: Set<Int> = setOf(429, 503, 504),
logFormatter: VertxHttpLoggingFormatter
logFormatter: VertxHttpLoggingFormatter,
): VertxHttpRequestSender {
val requestLogger = VertxRestRequestLogger(
log = logger,
requestResponseLogLevel = requestResponseLogLevel,
failuresLogLevel = failuresLogLevel,
logFormatter = logFormatter
logFormatter = logFormatter,
)
return createWithBaseSender(
vertx = vertx,
@@ -59,7 +59,7 @@ object VertxHttpRequestSenderFactory {
rateLimitBackoffDelay = rateLimitBackoffDelay,
retryableErrorCodes = retryableErrorCodes,
logFormatter = logFormatter,
baseRequestSender = SimpleVertxHttpRequestSender(requestLogger)
baseRequestSender = SimpleVertxHttpRequestSender(requestLogger),
)
}
}

View File

@@ -11,7 +11,7 @@ interface VertxRequestLogger {
fun logResponse(
request: HttpRequest<Buffer>,
response: HttpResponse<Buffer>? = null,
failureCause: Throwable? = null
failureCause: Throwable? = null,
)
}
@@ -19,18 +19,18 @@ class VertxRestRequestLogger(
private val log: Logger,
private val logFormatter: VertxHttpLoggingFormatter,
private val requestResponseLogLevel: Level = Level.TRACE,
private val failuresLogLevel: Level = Level.DEBUG
private val failuresLogLevel: Level = Level.DEBUG,
) : VertxRequestLogger {
constructor(
log: Logger,
responseLogMaxSize: UInt? = null,
requestResponseLogLevel: Level = Level.TRACE,
failuresLogLevel: Level = Level.DEBUG
failuresLogLevel: Level = Level.DEBUG,
) : this(
log = log,
logFormatter = VertxRestLoggingFormatter(responseLogMaxSize = responseLogMaxSize),
requestResponseLogLevel = requestResponseLogLevel,
failuresLogLevel = failuresLogLevel
failuresLogLevel = failuresLogLevel,
)
private fun logRequest(request: HttpRequest<Buffer>, logLevel: Level = requestResponseLogLevel) {
@@ -46,7 +46,7 @@ class VertxRestRequestLogger(
override fun logResponse(
request: HttpRequest<Buffer>,
response: HttpResponse<Buffer>?,
failureCause: Throwable?
failureCause: Throwable?,
) {
val isError = response?.statusCode()?.let(::isNotSuccessStatusCode) ?: true
val logLevel = if (isError) failuresLogLevel else requestResponseLogLevel

View File

@@ -17,15 +17,15 @@ class VertxRequestRetrier(
backoffDelay = requestRetryConfig.backoffDelay,
maxRetries = requestRetryConfig.maxRetries?.toInt(),
timeout = requestRetryConfig.timeout,
vertx = vertx
)
vertx = vertx,
),
) : VertxHttpRequestSender {
override fun makeRequest(request: HttpRequest<Buffer>): SafeFuture<HttpResponse<Buffer>> {
return asyncRetryer
.retry(
stopRetriesPredicate = { response: HttpResponse<Buffer> ->
response.statusCode() !in retryableErrorCodes
}
},
) {
requestSender.makeRequest(request)
}

View File

@@ -20,7 +20,7 @@ import kotlin.time.Duration
class BlobScanClient(
private val restClient: RestClient<JsonObject>,
private val log: Logger = LogManager.getLogger(BlobScanClient::class.java)
private val log: Logger = LogManager.getLogger(BlobScanClient::class.java),
) : BlobFetcher {
fun getBlobById(id: String): SafeFuture<ByteArray> {
return restClient
@@ -31,7 +31,7 @@ class BlobScanClient(
} else {
throw RuntimeException(
"error fetching blobId=$id " +
"errorMessage=${response.body?.getString("message") ?: ""}"
"errorMessage=${response.body?.getString("message") ?: ""}",
)
}
}
@@ -48,7 +48,7 @@ class BlobScanClient(
requestRetryConfig: RetryConfig,
rateLimitBackoffDelay: Duration? = null,
logger: Logger = LogManager.getLogger(BlobScanClient::class.java),
responseLogMaxSize: UInt? = 1000u
responseLogMaxSize: UInt? = 1000u,
): BlobScanClient {
val logFormatter = VertxRestLoggingFormatter(responseLogMaxSize = responseLogMaxSize)
@@ -61,16 +61,16 @@ class BlobScanClient(
logger = logger,
requestResponseLogLevel = Level.DEBUG,
failuresLogLevel = Level.DEBUG,
logFormatter = logFormatter
logFormatter = logFormatter,
)
val restClient = VertxRestClient(
webClient = WebClient.create(vertx, WebClientOptions().setDefaultsFrom(endpoint)),
responseParser = { it.toJsonObject() },
requestSender = requestSender
requestSender = requestSender,
)
return BlobScanClient(
restClient = restClient,
log = logger
log = logger,
)
}
}

View File

@@ -8,7 +8,7 @@ import tech.pegasys.teku.infrastructure.async.SafeFuture
// TODO: move to a common module
data class RestResponse<T>(
val statusCode: Int,
val body: T?
val body: T?,
)
interface RestClient<Response> {
@@ -20,13 +20,13 @@ class VertxRestClient<Response>(
private val webClient: WebClient,
private val responseParser: (Buffer) -> Response,
private val requestSender: VertxHttpRequestSender,
private val requestHeaders: Map<String, String> = mapOf("Accept" to "application/json")
private val requestHeaders: Map<String, String> = mapOf("Accept" to "application/json"),
) : RestClient<Response> {
override fun get(path: String): SafeFuture<RestResponse<Response>> {
return requestSender.makeRequest(
webClient
.get(path)
.apply { requestHeaders.forEach(::putHeader) }
.apply { requestHeaders.forEach(::putHeader) },
)
.thenApply { response ->
val parsedResponse = response.body()?.let(responseParser)

View File

@@ -16,17 +16,25 @@ import kotlin.time.TimeSource
fun httpResponse(
statusCode: Int = 200,
statusMessage: String = "OK",
body: Buffer = Buffer.buffer()
body: Buffer = Buffer.buffer(),
): HttpResponse<Buffer> {
return HttpResponseImpl(
/* version = */ HttpVersion.HTTP_1_1,
/* statusCode = */ statusCode,
/* statusMessage = */ statusMessage,
/* headers = */ HeadersMultiMap(),
/* trailers = */ HeadersMultiMap(),
/* cookies = */ emptyList<String>(),
/* body = */ body,
/* redirects = */ emptyList<String>()
/* version = */
HttpVersion.HTTP_1_1,
/* statusCode = */
statusCode,
/* statusMessage = */
statusMessage,
/* headers = */
HeadersMultiMap(),
/* trailers = */
HeadersMultiMap(),
/* cookies = */
emptyList<String>(),
/* body = */
body,
/* redirects = */
emptyList<String>(),
)
}
@@ -35,8 +43,8 @@ class FakeRequestSender(
VertxRestRequestLogger(
responseLogMaxSize = null,
requestResponseLogLevel = Level.DEBUG,
log = LogManager.getLogger(FakeRequestSender::class.java)
)
log = LogManager.getLogger(FakeRequestSender::class.java),
),
) : VertxHttpRequestSender {
private val monotonicClock = TimeSource.Monotonic
private var lastRequestTime = monotonicClock.markNow()

View File

@@ -23,7 +23,7 @@ class StaticVertxHttpRequestRateLimiterTest {
vertx = vertx,
requestSender = reqSender,
rateLimitBackoffDelay = rateLimitBackoffDelay,
requestLogFormatter = VertxRestLoggingFormatter()
requestLogFormatter = VertxRestLoggingFormatter(),
)
}

View File

@@ -28,10 +28,10 @@ class VertxHttpRequestRateLimiterAndRetryTest {
requestRetryConfig = RetryConfig(
maxRetries = 5u,
backoffDelay = 10.milliseconds,
timeout = rateLimitBackoffDelay * 30
timeout = rateLimitBackoffDelay * 30,
),
rateLimitBackoffDelay = rateLimitBackoffDelay,
logFormatter = VertxRestLoggingFormatter(responseLogMaxSize = 1000u)
logFormatter = VertxRestLoggingFormatter(responseLogMaxSize = 1000u),
)
// Warn: this does not work in io.github.hakky54:logcaptor
// don't have time to dig into it now. disabling it for now

View File

@@ -13,7 +13,7 @@ class VertxRestLoggingFormatterTest {
val request = WebClient.create(
Vertx.vertx(),
WebClientOptions()
.setDefaultsFrom(URI("http://service:9876/"))
.setDefaultsFrom(URI("http://service:9876/")),
)
.get("/users/1?appKey=SOME_APP_KEY")
@@ -21,7 +21,7 @@ class VertxRestLoggingFormatterTest {
return VertxRestLoggingFormatter(
includeFullUri = includeFullUri,
uriTransformer = { it.replace("SOME_APP_KEY", "***") },
responseLogMaxSize = null
responseLogMaxSize = null,
)
}
@@ -39,7 +39,7 @@ class VertxRestLoggingFormatterTest {
val response = httpResponse(
statusCode = 200,
statusMessage = "OK",
body = Buffer.buffer("some-response-body")
body = Buffer.buffer("some-response-body"),
)
assertThat(formatter(includeFullUri = false).toLogString(request, response))

View File

@@ -21,7 +21,7 @@ class VertxRestRequestLoggerTest {
override fun toLogString(
request: HttpRequest<Buffer>,
response: HttpResponse<Buffer>?,
failureCause: Throwable?
failureCause: Throwable?,
): String {
return "response-log-string"
}
@@ -29,14 +29,14 @@ class VertxRestRequestLoggerTest {
fun setUpLogger(
// we need to use a different logger name for each test
loggerName: String = "request-logger-test-" + Random.nextBytes(8).encodeHex()
loggerName: String = "request-logger-test-" + Random.nextBytes(8).encodeHex(),
): Pair<VertxRestRequestLogger, LogCaptor> {
val logCaptor: LogCaptor = LogCaptor.forName(loggerName)
return VertxRestRequestLogger(
log = LogManager.getLogger(loggerName),
logFormatter = FakeLogFormatter(),
requestResponseLogLevel = Level.TRACE,
failuresLogLevel = Level.DEBUG
failuresLogLevel = Level.DEBUG,
) to logCaptor
}

View File

@@ -32,13 +32,13 @@ class BlobScanClientTest {
fun setUp(vertx: Vertx) {
wiremock = WireMockServer(
WireMockConfiguration.options()
.dynamicPort()
.dynamicPort(),
)
.apply {
addMockServiceRequestListener(object : RequestListener {
override fun requestReceived(
request: com.github.tomakehurst.wiremock.http.Request,
response: com.github.tomakehurst.wiremock.http.Response
response: com.github.tomakehurst.wiremock.http.Response,
) {
// to debug
// println("request: ${request.url}")
@@ -55,8 +55,8 @@ class BlobScanClientTest {
requestRetryConfig = RetryConfig(
backoffDelay = 10.milliseconds,
maxRetries = 5u,
timeout = 5.seconds
)
timeout = 5.seconds,
),
)
}
@@ -78,8 +78,8 @@ class BlobScanClientTest {
.willReturn(
WireMock.ok()
.withHeader("Content-type", "application/json")
.withBody(successResponseBody(blobId, blobData))
)
.withBody(successResponseBody(blobId, blobData)),
),
)
assertThat(blobScanClient.getBlobById(blobId).get().encodeHex()).isEqualTo(blobData)
@@ -99,9 +99,9 @@ class BlobScanClientTest {
.withBody(
"""
{"message":"No blob with versioned hash or kzg commitment '$blobId'.","code":"NOT_FOUND"}
""".trimIndent()
)
)
""".trimIndent(),
),
),
)
assertThatThrownBy { blobScanClient.getBlobById(blobId).get() }
@@ -117,22 +117,22 @@ class BlobScanClientTest {
WireMock.get("/blobs/$blobId")
.inScenario("SERVER_ERROR")
.willReturn(WireMock.status(503))
.willSetStateTo("SERVER_ERROR_1")
.willSetStateTo("SERVER_ERROR_1"),
)
wiremock.stubFor(
WireMock.get("/blobs/$blobId")
.inScenario("SERVER_ERROR")
.whenScenarioStateIs("SERVER_ERROR_1")
.willReturn(WireMock.status(503))
.willSetStateTo("SERVER_OK")
.willSetStateTo("SERVER_OK"),
)
wiremock.stubFor(
WireMock.get("/blobs/$blobId")
.inScenario("SERVER_ERROR")
.whenScenarioStateIs("SERVER_OK")
.willReturn(
WireMock.okJson(successResponseBody(blobId, blobData))
)
WireMock.okJson(successResponseBody(blobId, blobData)),
),
)
assertThat(blobScanClient.getBlobById(blobId).get().encodeHex()).isEqualTo(blobData)
@@ -140,7 +140,7 @@ class BlobScanClientTest {
private fun successResponseBody(
blobId: String,
blobData: String
blobData: String,
): String {
return """
{

View File

@@ -13,7 +13,7 @@ import tech.pegasys.teku.infrastructure.async.SafeFuture
import java.net.URI
class VertxTransactionDetailsClient internal constructor(
private val jsonRpcClient: JsonRpcV2Client
private val jsonRpcClient: JsonRpcV2Client,
) : TransactionDetailsClient {
companion object {
@@ -21,14 +21,14 @@ class VertxTransactionDetailsClient internal constructor(
jsonRpcClientFactory: JsonRpcClientFactory,
endpoint: URI,
retryConfig: RequestRetryConfig,
logger: Logger = LogManager.getLogger(TransactionDetailsClient::class.java)
logger: Logger = LogManager.getLogger(TransactionDetailsClient::class.java),
): VertxTransactionDetailsClient {
return VertxTransactionDetailsClient(
jsonRpcClientFactory.createJsonRpcV2Client(
endpoints = listOf(endpoint),
retryConfig = retryConfig,
log = logger
)
log = logger,
),
)
}
}
@@ -44,7 +44,7 @@ class VertxTransactionDetailsClient internal constructor(
?.toList()
?.map { it.asText().decodeHex() }
?: emptyList()
}
},
)
}
}

View File

@@ -54,7 +54,7 @@ class StateRecoveryE2ETest {
fun beforeEach(vertx: Vertx) {
val jsonRpcFactory = VertxHttpJsonRpcClientFactory(
vertx = vertx,
metricsFacade = MicrometerMetricsFacade(SimpleMeterRegistry())
metricsFacade = MicrometerMetricsFacade(SimpleMeterRegistry()),
)
stateManagerClient = StateManagerV1JsonRpcClient.create(
@@ -63,10 +63,10 @@ class StateRecoveryE2ETest {
maxInflightRequestsPerClient = 1U,
requestRetry = RequestRetryConfig(
backoffDelay = 10.milliseconds,
timeout = 2.seconds
timeout = 2.seconds,
),
zkStateManagerVersion = "2.3.0",
logger = LogManager.getLogger("test.clients.l1.state-manager")
logger = LogManager.getLogger("test.clients.l1.state-manager"),
)
configureLoggers(
@@ -80,7 +80,7 @@ class StateRecoveryE2ETest {
"test.clients.l1.linea-contract" to Level.INFO,
"test.clients.l1.events-fetcher" to Level.INFO,
"test.clients.l1.blobscan" to Level.INFO,
"net.consensys.linea.contract.l1" to Level.INFO
"net.consensys.linea.contract.l1" to Level.INFO,
)
}
@@ -89,16 +89,16 @@ class StateRecoveryE2ETest {
Runner.executeCommandFailOnNonZeroExitCode(
command = "make start-env-with-staterecovery",
envVars = mapOf(
"L1_GENESIS_TIME" to Clock.System.now().plus(5.seconds).epochSeconds.toString()
"L1_GENESIS_TIME" to Clock.System.now().plus(5.seconds).epochSeconds.toString(),
),
timeout = 2.minutes
timeout = 2.minutes,
).get()
log.debug("stack restarted")
}
@Test
fun `should recover from middle of chain and be resilient to node restarts`(
vertx: Vertx
vertx: Vertx,
) {
// Part A:
// we shall have multiple finalizations on L1
@@ -128,15 +128,15 @@ class StateRecoveryE2ETest {
Web3jClientManager.buildL1Client(
log = LogManager.getLogger("test.clients.l1.events-fetcher"),
requestResponseLogLevel = Level.TRACE,
failuresLogLevel = Level.WARN
failuresLogLevel = Level.WARN,
),
requestRetryConfig = RetryConfig.noRetries,
vertx = null
vertx = null,
),
EthLogsSearcherImpl.Config(
loopSuccessBackoffDelay = 1.milliseconds
loopSuccessBackoffDelay = 1.milliseconds,
),
log = LogManager.getLogger("test.clients.l1.events-fetcher")
log = LogManager.getLogger("test.clients.l1.events-fetcher"),
)
val web3jElClient = createWeb3jHttpClient(executionLayerUrl)
log.info("starting test flow: besu staterecovery block={}", web3jElClient.ethBlockNumber().send().blockNumber)
@@ -167,7 +167,7 @@ class StateRecoveryE2ETest {
command = "make staterecovery-replay-from-block " +
"L1_ROLLUP_CONTRACT_ADDRESS=$localStackL1ContractAddress " +
"STATERECOVERY_OVERRIDE_START_BLOCK_NUMBER=$stateRecoveryStartBlockNumber",
log = log
log = log,
).get()
// No Errors should be logged in Besu
assertThat(getBesuErrorLogs()).isEmpty()
@@ -178,7 +178,7 @@ class StateRecoveryE2ETest {
web3jElClient,
stateManagerClient,
lastFinalizationA.event.endBlockNumber,
lastFinalizationA.event.finalStateRootHash
lastFinalizationA.event.finalStateRootHash,
)
// No Errors should be logged in Besu
assertThat(getBesuErrorLogs()).isEmpty()
@@ -200,7 +200,7 @@ class StateRecoveryE2ETest {
web3jElClient,
stateManagerClient,
lastFinalizationB.event.endBlockNumber,
lastFinalizationB.event.finalStateRootHash
lastFinalizationB.event.finalStateRootHash,
)
// No Errors should be logged in Besu
assertThat(getBesuErrorLogs()).isEmpty()
@@ -210,7 +210,7 @@ class StateRecoveryE2ETest {
log.info("Restarting zkbesu-shomei node")
execCommandAndAssertSuccess(
command = "docker restart -s 9 zkbesu-shomei-sr",
log = log
log = log,
).get()
// No Errors should be logged in Besu
assertThat(getBesuErrorLogs()).isEmpty()
@@ -237,31 +237,36 @@ class StateRecoveryE2ETest {
web3jElClient,
stateManagerClient,
lastFinalizationC.event.endBlockNumber,
lastFinalizationC.event.finalStateRootHash
lastFinalizationC.event.finalStateRootHash,
)
// No Errors should be logged in Besu
assertThat(getBesuErrorLogs()).isEmpty()
}
private fun sendTxToL2(
keepSendingPredicate: () -> Boolean
keepSendingPredicate: () -> Boolean,
) {
val account = L2AccountManager.generateAccount()
val txManager = L2AccountManager.getTransactionManager(account)
Thread {
while (keepSendingPredicate()) {
val txHash = txManager.sendTransaction(
/*gasPrice*/ 150UL.gwei.toBigInteger(),
/*gasLimit*/ 25_000UL.toBigInteger(),
/*to*/ account.address,
/*data*/ "",
/*value*/ 1UL.toBigInteger()
/*gasPrice*/
150UL.gwei.toBigInteger(),
/*gasLimit*/
25_000UL.toBigInteger(),
/*to*/
account.address,
/*data*/
"",
/*value*/
1UL.toBigInteger(),
).transactionHash
log.trace("sent tx to L2, txHash={}", txHash)
Web3jClientManager.l2Client.waitForTxReceipt(
txHash = txHash,
timeout = 5.seconds,
pollingInterval = 500.milliseconds
pollingInterval = 500.milliseconds,
)
}
}.start()

View File

@@ -39,7 +39,7 @@ class LineaSubmissionEventsClientIntTest {
private lateinit var submissionEventsFetcher: LineaRollupSubmissionEventsClient
private fun setupTest(
vertx: Vertx
vertx: Vertx,
) {
configureLoggers(
rootLevel = Level.INFO,
@@ -47,7 +47,7 @@ class LineaSubmissionEventsClientIntTest {
"test.clients.l1.executionlayer" to Level.INFO,
"test.clients.l1.web3j-default" to Level.INFO,
"test.clients.l1.linea-contract" to Level.INFO,
"test.clients.l1.events-fetcher" to Level.DEBUG
"test.clients.l1.events-fetcher" to Level.DEBUG,
)
val rollupDeploymentFuture = ContractsManager.get()
@@ -57,13 +57,13 @@ class LineaSubmissionEventsClientIntTest {
blobsResponsesDir = "$testDataDir/compression/responses",
aggregationsResponsesDir = "$testDataDir/aggregation/responses",
numberOfAggregations = 7,
extraBlobsWithoutAggregation = 3
extraBlobsWithoutAggregation = 3,
)
// wait smc deployment finishes
rollupDeploymentResult = rollupDeploymentFuture.get()
submissionEventsFetcher = createSubmissionEventsClient(
vertx = vertx,
contractAddress = rollupDeploymentResult.contractAddress
contractAddress = rollupDeploymentResult.contractAddress,
)
submitBlobsAndAggregationsAndWaitExecution(
@@ -71,24 +71,24 @@ class LineaSubmissionEventsClientIntTest {
contractClientForAggregationSubmission = connectToLineaRollupContract(
contractAddress = rollupDeploymentResult.contractAddress,
transactionManager = rollupDeploymentResult.rollupOperators[1].txManager,
smartContractErrors = lineaRollupContractErrors
smartContractErrors = lineaRollupContractErrors,
),
aggregationsAndBlobs = aggregationsAndBlobs,
blobChunksMaxSize = 9,
l1Web3jClient = Web3jClientManager.l1Client,
waitTimeout = 4.minutes
waitTimeout = 4.minutes,
)
}
private fun createSubmissionEventsClient(
vertx: Vertx,
contractAddress: String
contractAddress: String,
): LineaRollupSubmissionEventsClient {
val log = LogManager.getLogger("test.clients.l1.events-fetcher")
val eventsFetcherWeb3jClient = Web3jClientManager.buildL1Client(
log = log,
requestResponseLogLevel = Level.DEBUG,
failuresLogLevel = Level.WARN
failuresLogLevel = Level.WARN,
)
return LineaSubmissionEventsClientImpl(
logsSearcher = EthLogsSearcherImpl(
@@ -96,16 +96,16 @@ class LineaSubmissionEventsClientIntTest {
ethApiClient = createEthApiClient(
web3jClient = eventsFetcherWeb3jClient,
requestRetryConfig = RetryConfig.noRetries,
vertx = null
vertx = null,
),
config = EthLogsSearcherImpl.Config(
loopSuccessBackoffDelay = 1.milliseconds
loopSuccessBackoffDelay = 1.milliseconds,
),
log = log
log = log,
),
smartContractAddress = contractAddress,
l1LatestSearchBlock = BlockParameter.Tag.LATEST,
logsBlockChunkSize = 100
logsBlockChunkSize = 100,
)
}
@@ -125,8 +125,8 @@ class LineaSubmissionEventsClientIntTest {
submissionEventsFetcher
.findFinalizationAndDataSubmissionV3Events(
fromL1BlockNumber = BlockParameter.Tag.EARLIEST,
finalizationStartBlockNumber = expectedFinalizationEvent.startBlockNumber
)
finalizationStartBlockNumber = expectedFinalizationEvent.startBlockNumber,
),
)
.succeedsWithin(1.minutes.toJavaDuration())
.extracting { submissionEvents ->
@@ -146,8 +146,8 @@ class LineaSubmissionEventsClientIntTest {
submissionEventsFetcher
.findFinalizationAndDataSubmissionV3Events(
fromL1BlockNumber = BlockParameter.Tag.EARLIEST,
finalizationStartBlockNumber = invalidStartBlockNumber
).get()
finalizationStartBlockNumber = invalidStartBlockNumber,
).get(),
)
.isNull()
}
@@ -159,7 +159,7 @@ class LineaSubmissionEventsClientIntTest {
submissionEventsFetcher
.findFinalizationAndDataSubmissionV3EventsContainingL2BlockNumber(
fromL1BlockNumber = BlockParameter.Tag.EARLIEST,
l2BlockNumber = invalidStartBlockNumber
l2BlockNumber = invalidStartBlockNumber,
).get()
.also { result ->
assertThat(result).isNotNull
@@ -169,7 +169,7 @@ class LineaSubmissionEventsClientIntTest {
}
private fun getExpectedSubmissionEventsFromRecords(
aggregationsAndBlobs: List<AggregationAndBlobs>
aggregationsAndBlobs: List<AggregationAndBlobs>,
): List<Pair<DataFinalizedV3, List<DataSubmittedV3>>> {
return aggregationsAndBlobs
.filter { it.aggregation != null }
@@ -180,7 +180,7 @@ class LineaSubmissionEventsClientIntTest {
DataSubmittedV3(
parentShnarf = blobsChunk.first().blobCompressionProof!!.prevShnarf,
shnarf = blobsChunk.last().expectedShnarf,
finalStateRootHash = blobsChunk.last().blobCompressionProof!!.finalStateRootHash
finalStateRootHash = blobsChunk.last().blobCompressionProof!!.finalStateRootHash,
)
}
@@ -190,7 +190,7 @@ class LineaSubmissionEventsClientIntTest {
endBlockNumber = aggregation.endBlockNumber,
shnarf = aggBlobs.last().expectedShnarf,
parentStateRootHash = aggBlobs.first().blobCompressionProof!!.parentStateRootHash,
finalStateRootHash = aggBlobs.last().blobCompressionProof!!.finalStateRootHash
finalStateRootHash = aggBlobs.last().blobCompressionProof!!.finalStateRootHash,
) to expectedDataSubmittedEvents
}
}

View File

@@ -65,12 +65,12 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
blobsResponsesDir = "$testDataDir/compression/responses",
aggregationsResponsesDir = "$testDataDir/aggregation/responses",
numberOfAggregations = 4,
extraBlobsWithoutAggregation = 0
extraBlobsWithoutAggregation = 0,
)
fakeExecutionLayerClient = FakeExecutionLayerClient(
headBlock = BlockNumberAndHash(number = 0uL, hash = ByteArray(32) { 0 }),
initialStateRecoverStartBlockNumber = null,
loggerName = "test.fake.clients.l1.fake-execution-layer"
loggerName = "test.fake.clients.l1.fake-execution-layer",
)
fakeStateManagerClient =
FakeStateManagerClientBasedOnBlobsRecords(blobRecords = aggregationsAndBlobs.flatMap { it.blobs })
@@ -84,7 +84,7 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
l1PollingInterval = 100.milliseconds,
l1getLogsChunkSize = 1000u,
executionClientPollingInterval = 1.seconds,
smartContractAddress = rollupDeploymentResult.contractAddress
smartContractAddress = rollupDeploymentResult.contractAddress,
)
appClients = createAppClients(
@@ -93,14 +93,14 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
l1RpcEndpoint = URI(l1RpcUrl),
l1RequestRetryConfig = RetryConfig(backoffDelay = 2.seconds),
blobScanEndpoint = URI(blobScanUrl),
stateManagerClientEndpoint = URI("http://it-does-not-matter:5432")
stateManagerClientEndpoint = URI("http://it-does-not-matter:5432"),
)
contractClientForBlobSubmissions = rollupDeploymentResult.rollupOperatorClient
contractClientForAggregationSubmissions = connectToLineaRollupContract(
rollupDeploymentResult.contractAddress,
rollupDeploymentResult.rollupOperators[1].txManager,
smartContractErrors = lineaRollupContractErrors
smartContractErrors = lineaRollupContractErrors,
)
configureLoggers(
@@ -113,12 +113,12 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
"test.fake.clients.l1.fake-execution-layer" to Level.DEBUG,
"test.clients.l1.web3j-default" to Level.INFO,
"test.clients.l1.web3j.receipt-poller" to Level.INFO,
"linea.staterecovery.datafetching" to Level.INFO
"linea.staterecovery.datafetching" to Level.INFO,
)
}
fun instantiateStateRecoveryApp(
debugForceSyncStopBlockNumber: ULong? = null
debugForceSyncStopBlockNumber: ULong? = null,
): StateRecoveryApp {
return StateRecoveryApp(
vertx = vertx,
@@ -130,15 +130,15 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
blockHeaderStaticFields = BlockHeaderStaticFields.localDev,
lineaContractClient = appClients.lineaContractClient,
config = appConfigs.copy(
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber
)
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber,
),
)
}
private fun submitDataToL1ContactAndWaitExecution(
aggregationsAndBlobs: List<AggregationAndBlobs> = this.aggregationsAndBlobs,
blobChunksSize: Int = 9,
waitTimeout: Duration = 4.minutes
waitTimeout: Duration = 4.minutes,
) {
submitBlobsAndAggregationsAndWaitExecution(
contractClientForBlobSubmission = contractClientForBlobSubmissions,
@@ -148,8 +148,8 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
waitTimeout = waitTimeout,
l1Web3jClient = createWeb3jHttpClient(
rpcUrl = l1RpcUrl,
log = LogManager.getLogger("test.clients.l1.web3j.receipt-poller")
)
log = LogManager.getLogger("test.clients.l1.web3j.receipt-poller"),
),
)
}
@@ -162,7 +162,7 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
2. when state recovery enabled:
2.1 recoveryStartBlockNumber > headBlockNumber: pull for head block number until is reached and start recovery there
2.2 recoveryStartBlockNumber <= headBlockNumber: resume recovery from headBlockNumber
*/
*/
@Test
fun `when state recovery disabled and is starting from genesis`() {
instantiateStateRecoveryApp().start().get()
@@ -180,8 +180,8 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
.isEqualTo(
StateRecoveryStatus(
headBlockNumber = lastAggregation!!.endBlockNumber,
stateRecoverStartBlockNumber = 1UL
)
stateRecoverStartBlockNumber = 1UL,
),
)
}
@@ -204,16 +204,16 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
log.debug(
"finalizations={} finalizationToStartRecoveryFrom={}",
aggregationsAndBlobs.map { it.aggregation?.intervalString() },
finalizationToResumeFrom.intervalString()
finalizationToResumeFrom.intervalString(),
)
submitDataToL1ContactAndWaitExecution(
aggregationsAndBlobs = finalizationsBeforeCutOff
aggregationsAndBlobs = finalizationsBeforeCutOff,
)
fakeExecutionLayerClient.headBlock = BlockNumberAndHash(
number = 1UL,
hash = ByteArray(32) { 0 }
hash = ByteArray(32) { 0 },
)
val lastFinalizedBlockNumber = finalizationsBeforeCutOff.last().aggregation!!.endBlockNumber
@@ -227,8 +227,8 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
assertThat(fakeExecutionLayerClient.stateRecoverStatus).isEqualTo(
StateRecoveryStatus(
headBlockNumber = 1UL,
stateRecoverStartBlockNumber = expectedStateRecoverStartBlockNumber
)
stateRecoverStartBlockNumber = expectedStateRecoverStartBlockNumber,
),
)
log.info("stateRecoverStatus={}", fakeExecutionLayerClient.stateRecoverStatus)
}
@@ -236,12 +236,12 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
// simulate that execution client has synced up to the last finalized block through P2P network
fakeExecutionLayerClient.headBlock = BlockNumberAndHash(
number = lastFinalizedBlockNumber,
hash = ByteArray(32) { 0 }
hash = ByteArray(32) { 0 },
)
// continue finalizing the rest of the aggregations
submitDataToL1ContactAndWaitExecution(
aggregationsAndBlobs = finalizationsAfterCutOff
aggregationsAndBlobs = finalizationsAfterCutOff,
)
val lastAggregation = aggregationsAndBlobs.findLast { it.aggregation != null }!!.aggregation
@@ -277,18 +277,18 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
log.debug(
"finalizations={} finalizationToStartRecoveryFrom={}",
aggregationsAndBlobs.map { it.aggregation?.intervalString() },
finalizationToResumeFrom.intervalString()
finalizationToResumeFrom.intervalString(),
)
submitDataToL1ContactAndWaitExecution(
aggregationsAndBlobs = finalizationsBeforeCutOff
aggregationsAndBlobs = finalizationsBeforeCutOff,
)
// set execution layer head block after latest finalization
val headBlockNumberAtStart = finalizationsBeforeCutOff.last().aggregation!!.endBlockNumber + 1UL
fakeExecutionLayerClient.headBlock = BlockNumberAndHash(
number = headBlockNumberAtStart,
hash = ByteArray(32) { 0 }
hash = ByteArray(32) { 0 },
)
instantiateStateRecoveryApp().start().get()
await()
@@ -298,15 +298,15 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
assertThat(fakeExecutionLayerClient.stateRecoverStatus).isEqualTo(
StateRecoveryStatus(
headBlockNumber = headBlockNumberAtStart,
stateRecoverStartBlockNumber = headBlockNumberAtStart + 1UL
)
stateRecoverStartBlockNumber = headBlockNumberAtStart + 1UL,
),
)
log.debug("stateRecoverStatus={}", fakeExecutionLayerClient.stateRecoverStatus)
}
// continue finalizing the rest of the aggregations
submitDataToL1ContactAndWaitExecution(
aggregationsAndBlobs = finalizationsAfterCutOff
aggregationsAndBlobs = finalizationsAfterCutOff,
)
val lastAggregation = aggregationsAndBlobs.findLast { it.aggregation != null }!!.aggregation
@@ -318,8 +318,8 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
.isEqualTo(
StateRecoveryStatus(
headBlockNumber = lastAggregation!!.endBlockNumber,
stateRecoverStartBlockNumber = headBlockNumberAtStart + 1UL
)
stateRecoverStartBlockNumber = headBlockNumberAtStart + 1UL,
),
)
}
// assert it does not try to import blocks behind the head block
@@ -331,12 +331,12 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
fun `should stop recovery as soon as stateroot mismatches`() {
fakeStateManagerClient.setBlockStateRootHash(
aggregationsAndBlobs[1].aggregation!!.endBlockNumber,
ByteArray(32) { 1 }
ByteArray(32) { 1 },
)
log.debug(
"aggregations={} forcedMismatchAggregation={}",
aggregationsAndBlobs.map { it.aggregation?.intervalString() },
aggregationsAndBlobs[1].aggregation!!.intervalString()
aggregationsAndBlobs[1].aggregation!!.intervalString(),
)
val stateRecoverApp = instantiateStateRecoveryApp()
@@ -368,7 +368,7 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
log.debug(
"headBlockNumber={} forceSyncStopBlockNumber={}",
fakeExecutionLayerClient.headBlock.number,
debugForceSyncStopBlockNumber
debugForceSyncStopBlockNumber,
)
assertThat(fakeExecutionLayerClient.headBlock.number).isGreaterThanOrEqualTo(debugForceSyncStopBlockNumber)
}

View File

@@ -42,7 +42,7 @@ class StateRecoveryWithRealBesuAndStateManagerIntTest {
private val testDataDir = "testdata/coordinator/prover/v3/stateRecovery"
private val aggregationsAndBlobs: List<AggregationAndBlobs> = loadBlobsAndAggregationsSortedAndGrouped(
blobsResponsesDir = "$testDataDir/compression/responses",
aggregationsResponsesDir = "$testDataDir/aggregation/responses"
aggregationsResponsesDir = "$testDataDir/aggregation/responses",
)
private lateinit var rollupDeploymentResult: LineaRollupDeploymentResult
private lateinit var contractClientForBlobSubmission: LineaRollupSmartContractClient
@@ -54,7 +54,7 @@ class StateRecoveryWithRealBesuAndStateManagerIntTest {
fun beforeEach(vertx: Vertx) {
val jsonRpcFactory = VertxHttpJsonRpcClientFactory(
vertx = vertx,
metricsFacade = MicrometerMetricsFacade(SimpleMeterRegistry())
metricsFacade = MicrometerMetricsFacade(SimpleMeterRegistry()),
)
stateManagerClient = StateManagerV1JsonRpcClient.create(
@@ -63,10 +63,10 @@ class StateRecoveryWithRealBesuAndStateManagerIntTest {
maxInflightRequestsPerClient = 1U,
requestRetry = RequestRetryConfig(
backoffDelay = 1.seconds,
timeout = 4.seconds
timeout = 4.seconds,
),
zkStateManagerVersion = "2.3.0",
logger = LogManager.getLogger("test.clients.l1.state-manager")
logger = LogManager.getLogger("test.clients.l1.state-manager"),
)
configureLoggers(
@@ -74,7 +74,7 @@ class StateRecoveryWithRealBesuAndStateManagerIntTest {
log.name to Level.DEBUG,
"net.consensys.linea.contract.Web3JContractAsyncHelper" to Level.WARN, // silence noisy gasPrice Caps logs
"test.clients.l1.state-manager" to Level.DEBUG,
"test.clients.l1.web3j-default" to Level.DEBUG
"test.clients.l1.web3j-default" to Level.DEBUG,
)
}
@@ -90,7 +90,7 @@ class StateRecoveryWithRealBesuAndStateManagerIntTest {
rollupDeploymentResult.contractAddress,
// index 0 is the first operator in rollupOperatorClient
rollupDeploymentResult.rollupOperators[1].txManager,
smartContractErrors = lineaRollupContractErrors
smartContractErrors = lineaRollupContractErrors,
)
log.info("starting stack for recovery of state pushed to L1")
val staterecoveryNodesStartFuture = execCommandAndAssertSuccess(
@@ -98,7 +98,7 @@ class StateRecoveryWithRealBesuAndStateManagerIntTest {
"L1_ROLLUP_CONTRACT_ADDRESS=${rollupDeploymentResult.contractAddress} " +
"STATERECOVERY_OVERRIDE_START_BLOCK_NUMBER=1",
timeout = 1.minutes,
log = log
log = log,
).thenPeek {
log.info("make staterecovery-replay-from-block executed")
}
@@ -114,7 +114,7 @@ class StateRecoveryWithRealBesuAndStateManagerIntTest {
blobChunksMaxSize = 9,
l1Web3jClient = Web3jClientManager.l1Client,
waitTimeout = 4.minutes,
log = log
log = log,
)
log.info("finalization={} executed on l1", lastAggregation.intervalString())
}
@@ -125,13 +125,13 @@ class StateRecoveryWithRealBesuAndStateManagerIntTest {
assertBesuAndShomeiRecoveredAsExpected(
lastAggregationAndBlobs,
timeout = 5.minutes
timeout = 5.minutes,
)
}
private fun assertBesuAndShomeiRecoveredAsExpected(
targetAggregationAndBlobs: AggregationAndBlobs,
timeout: Duration
timeout: Duration,
) {
val targetAggregation = targetAggregationAndBlobs.aggregation!!
val expectedZkEndStateRootHash = targetAggregationAndBlobs.blobs.last().blobCompressionProof!!.finalStateRootHash
@@ -141,7 +141,7 @@ class StateRecoveryWithRealBesuAndStateManagerIntTest {
stateManagerClient = stateManagerClient,
targetAggregation.endBlockNumber,
expectedZkEndStateRootHash,
timeout = timeout
timeout = timeout,
)
}
}

View File

@@ -66,7 +66,7 @@ class SubmissionsFetchingTaskIntTest {
blobsResponsesDir = "$testDataDir/compression/responses",
aggregationsResponsesDir = "$testDataDir/aggregation/responses",
numberOfAggregations = 7,
extraBlobsWithoutAggregation = 0
extraBlobsWithoutAggregation = 0,
)
val rollupDeploymentResult = ContractsManager.get()
.deployLineaRollup(numberOfOperators = 2, contractVersion = LineaContractVersion.V6).get()
@@ -77,14 +77,14 @@ class SubmissionsFetchingTaskIntTest {
l1RpcEndpoint = URI(l1RpcUrl),
l1RequestRetryConfig = RetryConfig(backoffDelay = 2.seconds),
blobScanEndpoint = URI(blobScanUrl),
stateManagerClientEndpoint = URI("http://it-does-not-matter:5432")
stateManagerClientEndpoint = URI("http://it-does-not-matter:5432"),
)
contractClientForBlobSubmissions = rollupDeploymentResult.rollupOperatorClient
contractClientForAggregationSubmissions = connectToLineaRollupContract(
rollupDeploymentResult.contractAddress,
rollupDeploymentResult.rollupOperators[1].txManager,
smartContractErrors = lineaRollupContractErrors
smartContractErrors = lineaRollupContractErrors,
)
configureLoggers(
rootLevel = Level.INFO,
@@ -95,7 +95,7 @@ class SubmissionsFetchingTaskIntTest {
"linea.plugin.staterecovery.clients" to Level.DEBUG,
"test.clients.l1.web3j-default" to Level.INFO,
"test.clients.l1.web3j.receipt-poller" to Level.INFO,
"linea.staterecovery.datafetching" to Level.INFO
"linea.staterecovery.datafetching" to Level.INFO,
)
submitDataToL1ContactAndWaitExecution()
}
@@ -103,18 +103,18 @@ class SubmissionsFetchingTaskIntTest {
fun createFetcherTask(
l2StartBlockNumber: ULong,
debugForceSyncStopBlockNumber: ULong? = null,
queuesSizeLimit: Int = 2
queuesSizeLimit: Int = 2,
): SubmissionsFetchingTask {
val l1EventsClient = LineaSubmissionEventsClientImpl(
logsSearcher = appClients.ethLogsSearcher,
smartContractAddress = appClients.lineaContractClient.contractAddress,
l1LatestSearchBlock = BlockParameter.Tag.LATEST,
logsBlockChunkSize = 5000
logsBlockChunkSize = 5000,
)
val blobDecompressor: BlobDecompressorAndDeserializer = BlobDecompressorToDomainV1(
decompressor = GoNativeBlobDecompressorFactory.getInstance(BlobDecompressorVersion.V1_2_0),
staticFields = BlockHeaderStaticFields.localDev,
vertx = vertx
vertx = vertx,
)
return SubmissionsFetchingTask(
@@ -129,14 +129,14 @@ class SubmissionsFetchingTaskIntTest {
submissionEventsQueueLimit = queuesSizeLimit,
compressedBlobsQueueLimit = queuesSizeLimit,
targetDecompressedBlobsQueueLimit = queuesSizeLimit,
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber,
)
}
private fun submitDataToL1ContactAndWaitExecution(
aggregationsAndBlobs: List<AggregationAndBlobs> = this.aggregationsAndBlobs,
blobChunksSize: Int = 9,
waitTimeout: Duration = 4.minutes
waitTimeout: Duration = 4.minutes,
) {
submitBlobsAndAggregationsAndWaitExecution(
contractClientForBlobSubmission = contractClientForBlobSubmissions,
@@ -146,9 +146,9 @@ class SubmissionsFetchingTaskIntTest {
waitTimeout = waitTimeout,
l1Web3jClient = createWeb3jHttpClient(
rpcUrl = l1RpcUrl,
log = LogManager.getLogger("test.clients.l1.web3j.receipt-poller")
log = LogManager.getLogger("test.clients.l1.web3j.receipt-poller"),
),
log = log
log = log,
)
}
@@ -171,17 +171,17 @@ class SubmissionsFetchingTaskIntTest {
assertSubmissionsAreCorrectlyFetched(
l2StartBlockNumber = 1UL,
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber,
)
}
private fun assertSubmissionsAreCorrectlyFetched(
l2StartBlockNumber: ULong,
debugForceSyncStopBlockNumber: ULong? = null
debugForceSyncStopBlockNumber: ULong? = null,
) {
val submissionsFetcher = createFetcherTask(
l2StartBlockNumber = l2StartBlockNumber,
queuesSizeLimit = 2
queuesSizeLimit = 2,
)
.also { it.start() }
val expectedAggregationsAndBlobsToBeFetched =
@@ -208,7 +208,7 @@ class SubmissionsFetchingTaskIntTest {
?.also { nextSubmission ->
fetchedSubmissions.add(nextSubmission)
submissionsFetcher.pruneQueueForElementsUpToInclusive(
elHeadBlockNumber = nextSubmission.submissionEvents.dataFinalizedEvent.event.endBlockNumber
elHeadBlockNumber = nextSubmission.submissionEvents.dataFinalizedEvent.event.endBlockNumber,
)
}
assertThat(submissionsFetcher.finalizationsReadyToImport()).isLessThanOrEqualTo(2)
@@ -241,11 +241,11 @@ class SubmissionsFetchingTaskIntTest {
fun assertFetchedData(
fetchedData: SubmissionEventsAndData<BlockFromL1RecoveredData>,
sotAggregationData: AggregationAndBlobs
sotAggregationData: AggregationAndBlobs,
) {
assertEventMatchesAggregation(
fetchedData.submissionEvents.dataFinalizedEvent.event,
sotAggregationData.aggregation!!
sotAggregationData.aggregation!!,
)
assertThat(fetchedData.data.first().header.blockNumber)
.isEqualTo(sotAggregationData.blobs.first().startBlockNumber)
@@ -255,7 +255,7 @@ class SubmissionsFetchingTaskIntTest {
fun assertEventMatchesAggregation(
event: DataFinalizedV3,
aggregation: Aggregation
aggregation: Aggregation,
) {
assertThat(event.startBlockNumber).isEqualTo(aggregation.startBlockNumber)
assertThat(event.endBlockNumber).isEqualTo(aggregation.endBlockNumber)

View File

@@ -12,7 +12,7 @@ import tech.pegasys.teku.infrastructure.async.SafeFuture
class FakeExecutionLayerClient(
headBlock: BlockNumberAndHash = BlockNumberAndHash(number = 0uL, hash = ByteArray(32) { 0 }),
initialStateRecoverStartBlockNumber: ULong? = null,
loggerName: String? = null
loggerName: String? = null,
) : ExecutionLayerClient {
private val log = loggerName
?.let { LogManager.getLogger(loggerName) }
@@ -35,7 +35,7 @@ class FakeExecutionLayerClient(
val stateRecoverStatus: StateRecoveryStatus
get() = StateRecoveryStatus(
headBlockNumber = headBlock.number,
stateRecoverStartBlockNumber = stateRecoverStartBlockNumber
stateRecoverStartBlockNumber = stateRecoverStartBlockNumber,
)
@Synchronized
@@ -46,14 +46,14 @@ class FakeExecutionLayerClient(
@Synchronized
override fun lineaEngineImportBlocksFromBlob(
blocks: List<BlockFromL1RecoveredData>
blocks: List<BlockFromL1RecoveredData>,
): SafeFuture<Unit> {
if (log.isTraceEnabled) {
log.trace("lineaEngineImportBlocksFromBlob($blocks)")
} else {
val interval = CommonDomainFunctions.blockIntervalString(
blocks.first().header.blockNumber,
blocks.last().header.blockNumber
blocks.last().header.blockNumber,
)
log.debug("lineaEngineImportBlocksFromBlob(interval=$interval)")
}
@@ -64,7 +64,7 @@ class FakeExecutionLayerClient(
@Synchronized
override fun getBlockNumberAndHash(
blockParameter: BlockParameter
blockParameter: BlockParameter,
): SafeFuture<BlockNumberAndHash> {
log.trace("getBlockNumberAndHash($blockParameter): $headBlock")
return SafeFuture.completedFuture(headBlock)
@@ -78,7 +78,7 @@ class FakeExecutionLayerClient(
@Synchronized
override fun lineaEnableStateRecovery(
stateRecoverStartBlockNumber: ULong
stateRecoverStartBlockNumber: ULong,
): SafeFuture<StateRecoveryStatus> {
this.stateRecoverStartBlockNumber = stateRecoverStartBlockNumber
log.debug("lineaEnableStateRecovery($stateRecoverStartBlockNumber) = $stateRecoverStatus")

View File

@@ -18,7 +18,7 @@ import java.util.concurrent.ConcurrentHashMap
open class FakeStateManagerClient(
_blocksStateRootHashes: Map<ULong, ByteArray> = emptyMap(),
var headBlockNumber: ULong = _blocksStateRootHashes.keys.maxOrNull() ?: 0UL
var headBlockNumber: ULong = _blocksStateRootHashes.keys.maxOrNull() ?: 0UL,
) : StateManagerClientV1 {
open val blocksStateRootHashes: MutableMap<ULong, ByteArray> =
ConcurrentHashMap<ULong, ByteArray>(_blocksStateRootHashes)
@@ -33,8 +33,8 @@ open class FakeStateManagerClient(
?.let { SafeFuture.completedFuture(it) }
?: SafeFuture.failedFuture(
RuntimeException(
"StateRootHash not found for block=$blockNumber. available blocks: ${blocksStateRootHashes.keys}"
)
"StateRootHash not found for block=$blockNumber. available blocks: ${blocksStateRootHashes.keys}",
),
)
}
@@ -43,7 +43,7 @@ open class FakeStateManagerClient(
}
override fun rollupGetStateMerkleProofWithTypedError(
blockInterval: BlockInterval
blockInterval: BlockInterval,
): SafeFuture<Result<GetZkEVMStateMerkleProofResponse, ErrorResponse<StateManagerErrorType>>> {
// For state recovery, we just need the endStateRootHash
return getStateRootHash(blockInterval.endBlockNumber)
@@ -53,26 +53,26 @@ open class FakeStateManagerClient(
zkStateMerkleProof = ArrayNode(null),
zkParentStateRootHash = ByteArray(32),
zkEndStateRootHash = stateRootHash,
zkStateManagerVersion = "fake-version"
)
zkStateManagerVersion = "fake-version",
),
)
}
}
}
class FakeStateManagerClientBasedOnBlobsRecords(
val blobRecords: List<BlobRecord>
val blobRecords: List<BlobRecord>,
) : FakeStateManagerClient(
_blocksStateRootHashes = blobRecords
.associate { it.endBlockNumber to it.blobCompressionProof!!.finalStateRootHash }
.associate { it.endBlockNumber to it.blobCompressionProof!!.finalStateRootHash },
)
class FakeStateManagerClientReadFromL1(
headBlockNumber: ULong,
val logsSearcher: EthLogsSearcher,
val contractAddress: String
val contractAddress: String,
) : FakeStateManagerClient(
headBlockNumber = headBlockNumber
headBlockNumber = headBlockNumber,
) {
override fun getStateRootHash(blockNumber: ULong): SafeFuture<ByteArray> {
@@ -87,8 +87,8 @@ class FakeStateManagerClientReadFromL1(
topics = listOf(
DataFinalizedV3.topic,
null,
blockNumber.toHexStringUInt256()
)
blockNumber.toHexStringUInt256(),
),
).thenApply { logs ->
logs.firstOrNull()?.let { finalizationLog ->
DataFinalizedV3.fromEthLog(finalizationLog).event.finalStateRootHash

View File

@@ -34,7 +34,7 @@ open class TestRunner(
private val l1RpcUrl: String,
private val blobScanUrl: String,
private val blobScanRatelimitBackoffDelay: Duration? = 1.seconds,
private val debugForceSyncStopBlockNumber: ULong = ULong.MAX_VALUE
private val debugForceSyncStopBlockNumber: ULong = ULong.MAX_VALUE,
) {
private val log = LogManager.getLogger("test.case.TestRunner")
val appConfig = StateRecoveryApp.Config(
@@ -45,7 +45,7 @@ open class TestRunner(
executionClientPollingInterval = 1.seconds,
smartContractAddress = smartContractAddress,
l1getLogsChunkSize = 10_000u,
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber,
)
val appClients = createAppClients(
vertx = vertx,
@@ -56,17 +56,17 @@ open class TestRunner(
blobScanEndpoint = URI(blobScanUrl),
blobScanRequestRetryConfig = RetryConfig(backoffDelay = 10.milliseconds, timeout = 2.minutes),
blobscanRequestRateLimitBackoffDelay = blobScanRatelimitBackoffDelay,
stateManagerClientEndpoint = URI("http://it-does-not-matter:5432")
stateManagerClientEndpoint = URI("http://it-does-not-matter:5432"),
)
private val fakeExecutionLayerClient = FakeExecutionLayerClient(
headBlock = BlockNumberAndHash(number = l2RecoveryStartBlockNumber - 1UL, hash = ByteArray(32) { 0 }),
initialStateRecoverStartBlockNumber = l2RecoveryStartBlockNumber,
loggerName = "test.fake.clients.execution-layer"
loggerName = "test.fake.clients.execution-layer",
)
var fakeStateManagerClient: StateManagerClientV1 = FakeStateManagerClientReadFromL1(
headBlockNumber = ULong.MAX_VALUE,
logsSearcher = appClients.ethLogsSearcher,
contractAddress = StateRecoveryApp.Config.lineaSepolia.smartContractAddress
contractAddress = StateRecoveryApp.Config.lineaSepolia.smartContractAddress,
)
var stateRecoverApp: StateRecoveryApp = StateRecoveryApp(
vertx = vertx,
@@ -77,7 +77,7 @@ open class TestRunner(
transactionDetailsClient = appClients.transactionDetailsClient,
blockHeaderStaticFields = BlockHeaderStaticFields.localDev,
lineaContractClient = appClients.lineaContractClient,
config = appConfig
config = appConfig,
)
init {
@@ -86,12 +86,12 @@ open class TestRunner(
"linea.staterecovery" to Level.TRACE,
"linea.plugin.staterecovery" to Level.INFO,
"linea.plugin.staterecovery.clients.l1.blob-scan" to Level.TRACE,
"linea.plugin.staterecovery.clients.l1.logs-searcher" to Level.INFO
"linea.plugin.staterecovery.clients.l1.logs-searcher" to Level.INFO,
)
}
fun run(
timeout: kotlin.time.Duration = 10.minutes
timeout: kotlin.time.Duration = 10.minutes,
) {
log.info("Running test case")
stateRecoverApp.start().get()
@@ -113,7 +113,7 @@ fun main() {
l2RecoveryStartBlockNumber = 18_504_528UL,
l1RpcUrl = "https://mainnet.infura.io/v3/$infuraAppKey",
blobScanUrl = "https://api.blobscan.com/",
blobScanRatelimitBackoffDelay = 1.seconds
blobScanRatelimitBackoffDelay = 1.seconds,
)
// val sepoliaTestRunner = TestRunner(
// l1RpcUrl = "https://sepolia.infura.io/v3/$infuraAppKey",

View File

@@ -19,7 +19,7 @@ import kotlin.time.toJavaDuration
fun execCommandAndAssertSuccess(
command: String,
timeout: Duration = 1.minutes,
log: Logger
log: Logger,
): SafeFuture<CommandResult> {
return Runner
.executeCommandFailOnNonZeroExitCode(command, timeout = timeout, log = log)
@@ -35,7 +35,7 @@ fun assertBesuAndShomeiRecoveredAsExpected(
stateManagerClient: StateManagerClientV1,
expectedBlockNumber: ULong,
expectedZkEndStateRootHash: ByteArray,
timeout: Duration = 60.seconds
timeout: Duration = 60.seconds,
) {
await()
.pollInterval(1.seconds.toJavaDuration())
@@ -53,7 +53,7 @@ fun waitExecutionLayerToBeUpAndRunning(
executionLayerUrl: String,
expectedHeadBlockNumber: ULong = 0UL,
log: Logger,
timeout: Duration = 2.minutes
timeout: Duration = 2.minutes,
) {
val web3jElClient = createWeb3jHttpClient(executionLayerUrl)
await()

View File

@@ -7,7 +7,7 @@ import linea.staterecovery.DataFinalizedV3
fun getLastFinalizationOnL1(
logsSearcher: EthLogsSearcherImpl,
contractAddress: String
contractAddress: String,
): EthLogEvent<DataFinalizedV3> {
return getFinalizationsOnL1(logsSearcher, contractAddress)
.lastOrNull()
@@ -16,12 +16,12 @@ fun getLastFinalizationOnL1(
fun getFinalizationsOnL1(
logsSearcher: EthLogsSearcherImpl,
contractAddress: String
contractAddress: String,
): List<EthLogEvent<DataFinalizedV3>> {
return logsSearcher.getLogs(
fromBlock = BlockParameter.Tag.EARLIEST,
toBlock = BlockParameter.Tag.LATEST,
address = contractAddress,
topics = listOf(DataFinalizedV3.topic)
topics = listOf(DataFinalizedV3.topic),
).get().map(DataFinalizedV3.Companion::fromEthLog)
}

View File

@@ -118,18 +118,13 @@ allprojects {
indentWithSpaces(2)
endWithNewline()
}
}
// TODO in later ticket - apply these linting rules to all monorepo projects
if (subproject.path.startsWith(':besu-plugins:linea-sequencer')) {
subproject.spotless {
java {
target 'src/**/*.java'
targetExclude '**/src/test/java/**ReferenceTest**', '**/src/main/generated/**', '**/src/test/generated/**', '**/src/jmh/generated/**'
removeUnusedImports()
trimTrailingWhitespace()
endWithNewline()
}
java {
target 'src/**/*.java'
targetExclude '**/src/test/java/**ReferenceTest**', '**/src/main/generated/**', '**/src/test/generated/**', '**/src/jmh/generated/**'
removeUnusedImports()
trimTrailingWhitespace()
endWithNewline()
}
}
}

View File

@@ -19,7 +19,7 @@ import org.apache.logging.log4j.Logger
import java.nio.file.Path
inline fun <reified T : Any> loadConfigsOrError(
configFiles: List<Path>
configFiles: List<Path>,
): Result<T, String> {
val confBuilder: ConfigLoaderBuilder = ConfigLoaderBuilder.Companion
.empty()
@@ -43,7 +43,7 @@ fun logErrorIfPresent(
configName: String,
configFiles: List<Path>,
configLoadingResult: Result<Any?, String>,
logger: Logger
logger: Logger,
) {
if (configLoadingResult is Err) {
logger.error("Failed to load $configName from files=$configFiles with error=${configLoadingResult.error}")
@@ -53,7 +53,7 @@ fun logErrorIfPresent(
inline fun <reified T : Any> loadConfigsAndLogErrors(
configFiles: List<Path>,
configName: String,
logger: Logger = LogManager.getLogger("linea.coordinator.config")
logger: Logger = LogManager.getLogger("linea.coordinator.config"),
): Result<T, String> {
return loadConfigsOrError<T>(configFiles)
.also { logErrorIfPresent(configName, configFiles, it, logger) }
@@ -64,7 +64,7 @@ fun loadConfigsOrError(
tracesLimitsFileV2: Path,
gasPriceCapTimeOfDayMultipliersFile: Path,
smartContractErrorsFile: Path,
logger: Logger = LogManager.getLogger("linea.coordinator.config")
logger: Logger = LogManager.getLogger("linea.coordinator.config"),
): Result<CoordinatorConfigTomlDto, String> {
val coordinatorBaseConfigs =
loadConfigsAndLogErrors<CoordinatorConfigTomlDto>(coordinatorConfigFiles, "coordinator", logger)
@@ -74,18 +74,18 @@ fun loadConfigsOrError(
loadConfigsAndLogErrors<GasPriceCapTimeOfDayMultipliersConfig>(
listOf(gasPriceCapTimeOfDayMultipliersFile),
"l1 submission gas prices caps",
logger
logger,
)
val smartContractErrorsConfig = loadConfigsAndLogErrors<SmartContractErrorCodesConfig>(
listOf(smartContractErrorsFile),
"smart contract errors",
logger
logger,
)
val configError = listOf(
coordinatorBaseConfigs,
tracesLimitsV2Configs,
gasPriceCapTimeOfDayMultipliersConfig,
smartContractErrorsConfig
smartContractErrorsConfig,
)
.find { it is Err }
@@ -98,13 +98,13 @@ fun loadConfigsOrError(
val finalConfig = baseConfig.copy(
conflation = baseConfig.conflation.copy(
_tracesLimitsV2 = tracesLimitsV2Configs.get()?.tracesLimits?.let { TracesCountersV2(it) },
_smartContractErrors = smartContractErrorsConfig.get()!!.smartContractErrors
_smartContractErrors = smartContractErrorsConfig.get()!!.smartContractErrors,
),
l1DynamicGasPriceCapService = baseConfig.l1DynamicGasPriceCapService.copy(
gasPriceCapCalculation = baseConfig.l1DynamicGasPriceCapService.gasPriceCapCalculation.copy(
timeOfDayMultipliers = gasPriceCapTimeOfDayMultipliersConfig.get()?.gasPriceCapTimeOfDayMultipliers
)
)
timeOfDayMultipliers = gasPriceCapTimeOfDayMultipliersConfig.get()?.gasPriceCapTimeOfDayMultipliers,
),
),
)
return Ok(finalConfig)
}
@@ -114,14 +114,14 @@ fun loadConfigs(
tracesLimitsFileV2: Path,
gasPriceCapTimeOfDayMultipliersFile: Path,
smartContractErrorsFile: Path,
logger: Logger = LogManager.getLogger("linea.coordinator.config")
logger: Logger = LogManager.getLogger("linea.coordinator.config"),
): CoordinatorConfig {
loadConfigsOrError(
coordinatorConfigFiles,
tracesLimitsFileV2,
gasPriceCapTimeOfDayMultipliersFile,
smartContractErrorsFile,
logger
logger,
).let {
return it
.getOrElse {

View File

@@ -6,10 +6,10 @@ import net.consensys.linea.vertx.ObservabilityServer
class Api(
private val configs: Config,
private val vertx: Vertx
private val vertx: Vertx,
) {
data class Config(
val observabilityPort: UInt
val observabilityPort: UInt,
)
private var observabilityServerId: String? = null

View File

@@ -23,7 +23,7 @@ import java.net.URI
fun createTransactionManager(
vertx: Vertx,
signerConfig: SignerConfig,
client: Web3j
client: Web3j,
): AsyncFriendlyTransactionManager {
val transactionSignService = when (signerConfig.type) {
SignerConfig.Type.Web3j -> {
@@ -57,7 +57,7 @@ fun createLineaRollupContractClient(
contractGasProvider: ContractGasProvider,
web3jClient: Web3j,
smartContractErrors: SmartContractErrors,
useEthEstimateGas: Boolean
useEthEstimateGas: Boolean,
): LineaRollupSmartContractClient {
return Web3JLineaRollupSmartContractClient.load(
contractAddress = l1Config.zkEvmContractAddress,
@@ -65,6 +65,6 @@ fun createLineaRollupContractClient(
transactionManager = transactionManager,
contractGasProvider = contractGasProvider,
smartContractErrors = smartContractErrors,
useEthEstimateGas = useEthEstimateGas
useEthEstimateGas = useEthEstimateGas,
)
}

View File

@@ -51,20 +51,20 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
vertx = vertx,
metricsFacade = MicrometerMetricsFacade(meterRegistry),
requestResponseLogLevel = Level.TRACE,
failuresLogLevel = Level.WARN
failuresLogLevel = Level.WARN,
)
private val api = Api(
Api.Config(
configs.api.observabilityPort
configs.api.observabilityPort,
),
vertx
vertx,
)
private val l2Web3jClient: Web3j = createWeb3jHttpClient(
rpcUrl = configs.l2.rpcEndpoint.toString(),
log = LogManager.getLogger("clients.l2.eth-api.rpc-node"),
pollingInterval = 1.seconds,
requestResponseLogLevel = Level.TRACE,
failuresLogLevel = Level.DEBUG
failuresLogLevel = Level.DEBUG,
)
private val persistenceRetryer = PersistenceRetryer(
@@ -72,8 +72,8 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
config = PersistenceRetryer.Config(
backoffDelay = configs.persistenceRetry.backoffDelay.toKotlinDuration(),
maxRetries = configs.persistenceRetry.maxRetries,
timeout = configs.persistenceRetry.timeout?.toKotlinDuration()
)
timeout = configs.persistenceRetry.timeout?.toKotlinDuration(),
),
)
private val sqlClient: SqlClient = initDb(configs.database)
@@ -81,10 +81,10 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
PostgresBatchesRepository(
batchesDao = RetryingBatchesPostgresDao(
delegate = BatchesPostgresDao(
connection = sqlClient
connection = sqlClient,
),
persistenceRetryer = persistenceRetryer
)
persistenceRetryer = persistenceRetryer,
),
)
private val blobsRepository =
@@ -92,21 +92,21 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
blobsDao = RetryingBlobsPostgresDao(
delegate = BlobsPostgresDao(
config = BlobsPostgresDao.Config(
maxBlobsToReturn = configs.blobSubmission.maxBlobsToReturn.toUInt()
maxBlobsToReturn = configs.blobSubmission.maxBlobsToReturn.toUInt(),
),
connection = sqlClient
connection = sqlClient,
),
persistenceRetryer = persistenceRetryer
)
persistenceRetryer = persistenceRetryer,
),
)
private val aggregationsRepository = AggregationsRepositoryImpl(
aggregationsPostgresDao = RetryingPostgresAggregationsDao(
delegate = PostgresAggregationsDao(
connection = sqlClient
connection = sqlClient,
),
persistenceRetryer = persistenceRetryer
)
persistenceRetryer = persistenceRetryer,
),
)
private val l1FeeHistoriesRepository =
@@ -116,11 +116,11 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
minBaseFeePerBlobGasToCache =
configs.l1DynamicGasPriceCapService.gasPriceCapCalculation.historicBaseFeePerBlobGasLowerBound,
fixedAverageRewardToCache =
configs.l1DynamicGasPriceCapService.gasPriceCapCalculation.historicAvgRewardConstant
configs.l1DynamicGasPriceCapService.gasPriceCapCalculation.historicAvgRewardConstant,
),
FeeHistoriesPostgresDao(
sqlClient
)
sqlClient,
),
)
private val l1App = L1DependentApp(
@@ -133,7 +133,7 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
aggregationsRepository = aggregationsRepository,
l1FeeHistoriesRepository = l1FeeHistoriesRepository,
smartContractErrors = configs.conflation.smartContractErrors,
metricsFacade = micrometerMetricsFacade
metricsFacade = micrometerMetricsFacade,
)
private val requestFileCleanup = DirectoryCleaner(
@@ -144,7 +144,7 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
configs.proversConfig.proverA.proofAggregation.requestsDirectory,
configs.proversConfig.proverB?.execution?.requestsDirectory,
configs.proversConfig.proverB?.blobCompression?.requestsDirectory,
configs.proversConfig.proverB?.proofAggregation?.requestsDirectory
configs.proversConfig.proverB?.proofAggregation?.requestsDirectory,
),
fileFilters = DirectoryCleaner.getSuffixFileFilters(
listOfNotNull(
@@ -153,9 +153,9 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
configs.proversConfig.proverA.proofAggregation.inprogressRequestWritingSuffix,
configs.proversConfig.proverB?.execution?.inprogressRequestWritingSuffix,
configs.proversConfig.proverB?.blobCompression?.inprogressRequestWritingSuffix,
configs.proversConfig.proverB?.proofAggregation?.inprogressRequestWritingSuffix
)
) + DirectoryCleaner.JSON_FILE_FILTER
configs.proversConfig.proverB?.proofAggregation?.inprogressRequestWritingSuffix,
),
) + DirectoryCleaner.JSON_FILE_FILTER,
)
init {
@@ -176,7 +176,7 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
SafeFuture.allOf(
l1App.stop(),
SafeFuture.fromRunnable { l2Web3jClient.shutdown() },
api.stop().toSafeFuture()
api.stop().toSafeFuture(),
).thenApply {
LoadBalancingJsonRpcClient.stop()
}.thenCompose {
@@ -201,7 +201,7 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
database = dbConfig.schema,
target = dbVersion,
username = dbConfig.username,
password = dbConfig.password.value
password = dbConfig.password.value,
)
return Db.vertxSqlClient(
vertx = vertx,
@@ -211,7 +211,7 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
username = dbConfig.username,
password = dbConfig.password.value,
maxPoolSize = dbConfig.transactionalPoolSize,
pipeliningLimit = dbConfig.readPipeliningLimit
pipeliningLimit = dbConfig.readPipeliningLimit,
)
}
}

View File

@@ -20,7 +20,7 @@ import java.util.concurrent.Callable
synopsisHeading = "%n",
descriptionHeading = "%nDescription:%n%n",
optionListHeading = "%nOptions:%n",
footerHeading = "%n"
footerHeading = "%n",
)
class CoordinatorAppCli
internal constructor(private val errorWriter: PrintWriter, private val startAction: StartAction) :
@@ -32,7 +32,7 @@ internal constructor(private val errorWriter: PrintWriter, private val startActi
names = ["--traces-limits-v2"],
paramLabel = "<FILE>",
description = ["Prover traces limits for linea besu"],
arity = "1"
arity = "1",
)
private val tracesLimitsV2File: File? = null
@@ -40,27 +40,24 @@ internal constructor(private val errorWriter: PrintWriter, private val startActi
names = ["--smart-contract-errors"],
paramLabel = "<FILE>",
description = ["Smart contract error codes"],
arity = "1"
arity = "1",
)
private val smartContractErrorsFile: File? = null
@CommandLine.Option(
names = ["--gas-price-cap-time-of-day-multipliers"],
paramLabel = "<FILE>",
description = ["Time-of-day multipliers for calculation of L1 dynamic gas price caps"],
arity = "1"
arity = "1",
)
private val gasPriceCapTimeOfDayMultipliersFile: File? = null
@CommandLine.Option(
names = ["--check-configs-only"],
paramLabel = "<BOOLEAN>",
description = ["Validates configuration files only, without starting the application."],
arity = "0..1"
arity = "0..1",
)
private var checkConfigsOnly: Boolean = false
override fun call(): Int {
@@ -97,7 +94,7 @@ internal constructor(private val errorWriter: PrintWriter, private val startActi
tracesLimitsFileV2 = tracesLimitsV2File.toPath(),
smartContractErrorsFile = smartContractErrorsFile.toPath(),
gasPriceCapTimeOfDayMultipliersFile = gasPriceCapTimeOfDayMultipliersFile.toPath(),
logger = logger
logger = logger,
)
if (checkConfigsOnly) {

View File

@@ -39,7 +39,7 @@ class CoordinatorAppMain {
// Messages in App.stop won't appear in the logs
Configurator.shutdown(LogManager.getContext() as LoggerContext)
}
}
},
)
app.start()
}

View File

@@ -116,7 +116,7 @@ class L1DependentApp(
private val aggregationsRepository: AggregationsRepository,
l1FeeHistoriesRepository: FeeHistoriesRepositoryWithCache,
private val smartContractErrors: SmartContractErrors,
private val metricsFacade: MetricsFacade
private val metricsFacade: MetricsFacade,
) : LongRunningService {
private val log = LogManager.getLogger(this::class.java)
@@ -132,13 +132,13 @@ class L1DependentApp(
private val l2TransactionManager = createTransactionManager(
vertx,
configs.l2Signer,
l2Web3jClient
l2Web3jClient,
)
private val l1Web3jClient = createWeb3jHttpClient(
rpcUrl = configs.l1.rpcEndpoint.toString(),
log = LogManager.getLogger("clients.l1.eth-api"),
pollingInterval = 1.seconds
pollingInterval = 1.seconds,
)
private val l1Web3jService = Web3jBlobExtended(HttpService(configs.l1.ethFeeHistoryEndpoint.toString()))
@@ -147,7 +147,7 @@ class L1DependentApp(
private val proverClientFactory = ProverClientFactory(
vertx = vertx,
config = configs.proversConfig,
metricsFacade = metricsFacade
metricsFacade = metricsFacade,
)
private val l2ExtendedWeb3j = ExtendedWeb3JImpl(l2Web3jClient)
@@ -155,32 +155,32 @@ class L1DependentApp(
private val finalizationTransactionManager = createTransactionManager(
vertx,
configs.finalizationSigner,
l1Web3jClient
l1Web3jClient,
)
private val l1MinPriorityFeeCalculator: FeesCalculator = WMAFeesCalculator(
WMAFeesCalculator.Config(
baseFeeCoefficient = 0.0,
priorityFeeWmaCoefficient = 1.0
)
priorityFeeWmaCoefficient = 1.0,
),
)
private val l1DataSubmissionPriorityFeeCalculator: FeesCalculator = BoundableFeeCalculator(
BoundableFeeCalculator.Config(
feeUpperBound = configs.blobSubmission.priorityFeePerGasUpperBound.toDouble(),
feeLowerBound = configs.blobSubmission.priorityFeePerGasLowerBound.toDouble(),
feeMargin = 0.0
feeMargin = 0.0,
),
l1MinPriorityFeeCalculator
l1MinPriorityFeeCalculator,
)
private val l1FinalizationPriorityFeeCalculator: FeesCalculator = BoundableFeeCalculator(
BoundableFeeCalculator.Config(
feeUpperBound = configs.l1.maxPriorityFeePerGasCap.toDouble() * configs.l1.gasPriceCapMultiplierForFinalization,
feeLowerBound = 0.0,
feeMargin = 0.0
feeMargin = 0.0,
),
l1MinPriorityFeeCalculator
l1MinPriorityFeeCalculator,
)
private val feesFetcher: FeesFetcher = FeeHistoryFetcherImpl(
@@ -188,13 +188,13 @@ class L1DependentApp(
l1Web3jService,
FeeHistoryFetcherImpl.Config(
configs.l1.feeHistoryBlockCount.toUInt(),
configs.l1.feeHistoryRewardPercentile
)
configs.l1.feeHistoryRewardPercentile,
),
)
private val lineaRollupClient: LineaRollupSmartContractClientReadOnly = Web3JLineaRollupSmartContractClientReadOnly(
contractAddress = configs.l1.zkEvmContractAddress,
web3j = l1Web3jClient
web3j = l1Web3jClient,
)
private val l1FinalizationMonitor = run {
@@ -202,11 +202,11 @@ class L1DependentApp(
config =
FinalizationMonitorImpl.Config(
pollingInterval = configs.l1.finalizationPollingInterval.toKotlinDuration(),
l1QueryBlockTag = configs.l1.l1QueryBlockTag
l1QueryBlockTag = configs.l1.l1QueryBlockTag,
),
contract = lineaRollupClient,
l2Client = l2Web3jClient,
vertx = vertx
vertx = vertx,
)
}
@@ -215,7 +215,7 @@ class L1DependentApp(
httpJsonRpcClientFactory = httpJsonRpcClientFactory,
lineaRollupClient = lineaRollupClient,
l2Web3jClient = l2Web3jClient,
vertx = vertx
vertx = vertx,
)
private val gasPriceCapProvider =
@@ -246,11 +246,11 @@ class L1DependentApp(
finalizationTargetMaxDelay =
configs.l1DynamicGasPriceCapService.gasPriceCapCalculation.finalizationTargetMaxDelay.toKotlinDuration(),
gasPriceCapsCoefficient =
configs.l1DynamicGasPriceCapService.gasPriceCapCalculation.gasPriceCapsCheckCoefficient
configs.l1DynamicGasPriceCapService.gasPriceCapCalculation.gasPriceCapsCheckCoefficient,
),
l2ExtendedWeb3JClient = l2ExtendedWeb3j,
feeHistoriesRepository = l1FeeHistoriesRepository,
gasPriceCapCalculator = l1GasPriceCapCalculator
gasPriceCapCalculator = l1GasPriceCapCalculator,
)
} else {
null
@@ -261,10 +261,10 @@ class L1DependentApp(
config = GasPriceCapProviderForDataSubmission.Config(
maxPriorityFeePerGasCap = configs.l1.maxPriorityFeePerGasCap,
maxFeePerGasCap = configs.l1.maxFeePerGasCap,
maxFeePerBlobGasCap = configs.l1.maxFeePerBlobGasCap
maxFeePerBlobGasCap = configs.l1.maxFeePerBlobGasCap,
),
gasPriceCapProvider = gasPriceCapProvider!!,
metricsFacade = metricsFacade
metricsFacade = metricsFacade,
)
} else {
null
@@ -275,10 +275,10 @@ class L1DependentApp(
config = GasPriceCapProviderForFinalization.Config(
maxPriorityFeePerGasCap = configs.l1.maxPriorityFeePerGasCap,
maxFeePerGasCap = configs.l1.maxFeePerGasCap,
gasPriceCapMultiplier = configs.l1.gasPriceCapMultiplierForFinalization
gasPriceCapMultiplier = configs.l1.gasPriceCapMultiplierForFinalization,
),
gasPriceCapProvider = gasPriceCapProvider!!,
metricsFacade = metricsFacade
metricsFacade = metricsFacade,
)
} else {
null
@@ -287,11 +287,11 @@ class L1DependentApp(
private val lastFinalizedBlock = lastFinalizedBlock().get()
private val lastProcessedBlockNumber = resumeConflationFrom(
aggregationsRepository,
lastFinalizedBlock
lastFinalizedBlock,
).get()
private val lastConsecutiveAggregatedBlockNumber = resumeAggregationFrom(
aggregationsRepository,
lastFinalizedBlock
lastFinalizedBlock,
).get()
private fun createDeadlineConflationCalculatorRunner(): DeadlineConflationCalculatorRunner {
@@ -301,15 +301,15 @@ class L1DependentApp(
config = ConflationCalculatorByTimeDeadline.Config(
conflationDeadline = configs.conflation.conflationDeadline.toKotlinDuration(),
conflationDeadlineLastBlockConfirmationDelay =
configs.conflation.conflationDeadlineLastBlockConfirmationDelay.toKotlinDuration()
configs.conflation.conflationDeadlineLastBlockConfirmationDelay.toKotlinDuration(),
),
lastBlockNumber = lastProcessedBlockNumber,
clock = Clock.System,
latestBlockProvider = GethCliqueSafeBlockProvider(
l2ExtendedWeb3j.web3jClient,
GethCliqueSafeBlockProvider.Config(configs.l2.blocksToFinalization.toLong())
)
)
GethCliqueSafeBlockProvider.Config(configs.l2.blocksToFinalization.toLong()),
),
),
)
}
@@ -320,8 +320,8 @@ class L1DependentApp(
if (configs.conflation.blocksLimit != null) {
calculators.add(
ConflationCalculatorByBlockLimit(
blockLimit = configs.conflation.blocksLimit.toUInt()
)
blockLimit = configs.conflation.blocksLimit.toUInt(),
),
)
}
}
@@ -330,15 +330,15 @@ class L1DependentApp(
if (configs.conflation.conflationTargetEndBlockNumbers.isNotEmpty()) {
calculators.add(
ConflationCalculatorByTargetBlockNumbers(
targetEndBlockNumbers = configs.conflation.conflationTargetEndBlockNumbers
)
targetEndBlockNumbers = configs.conflation.conflationTargetEndBlockNumbers,
),
)
}
}
private fun createCalculatorsForBlobsAndConflation(
logger: Logger,
compressedBlobCalculator: ConflationCalculatorByDataCompressed
compressedBlobCalculator: ConflationCalculatorByDataCompressed,
): List<ConflationCalculator> {
val calculators: MutableList<ConflationCalculator> =
mutableListOf(
@@ -346,9 +346,9 @@ class L1DependentApp(
tracesCountersLimit = configs.conflation.tracesLimitsV2,
emptyTracesCounters = TracesCountersV2.EMPTY_TRACES_COUNT,
metricsFacade = metricsFacade,
log = logger
log = logger,
),
compressedBlobCalculator
compressedBlobCalculator,
)
addBlocksLimitCalculatorIfDefined(calculators)
addTargetEndBlockConflationCalculatorIfDefined(calculators)
@@ -363,18 +363,18 @@ class L1DependentApp(
val blobCompressor = GoBackedBlobCompressor.getInstance(
compressorVersion = compressorVersion,
dataLimit = configs.blobCompression.blobSizeLimit.toUInt(),
metricsFacade = metricsFacade
metricsFacade = metricsFacade,
)
val compressedBlobCalculator = ConflationCalculatorByDataCompressed(
blobCompressor = blobCompressor
blobCompressor = blobCompressor,
)
val globalCalculator = GlobalBlockConflationCalculator(
lastBlockNumber = lastProcessedBlockNumber,
syncCalculators = createCalculatorsForBlobsAndConflation(logger, compressedBlobCalculator),
deferredTriggerConflationCalculators = listOf(deadlineConflationCalculatorRunnerNew),
emptyTracesCounters = TracesCountersV2.EMPTY_TRACES_COUNT,
log = logger
log = logger,
)
val batchesLimit =
@@ -384,7 +384,7 @@ class L1DependentApp(
conflationCalculator = globalCalculator,
blobCalculator = compressedBlobCalculator,
metricsFacade = metricsFacade,
batchesLimit = batchesLimit
batchesLimit = batchesLimit,
)
}
private val conflationService: ConflationService =
@@ -396,7 +396,7 @@ class L1DependentApp(
maxInflightRequestsPerClient = configs.stateManager.requestLimitPerEndpoint,
requestRetry = configs.stateManager.requestRetryConfig,
zkStateManagerVersion = configs.stateManager.version,
logger = LogManager.getLogger("clients.StateManagerShomeiClient")
logger = LogManager.getLogger("clients.StateManagerShomeiClient"),
)
private val lineaSmartContractClientForDataSubmission: LineaRollupSmartContractClient = run {
@@ -411,26 +411,26 @@ class L1DependentApp(
gasLimit = configs.l1.gasLimit,
maxFeePerGasCap = configs.l1.maxFeePerGasCap,
maxPriorityFeePerGasCap = configs.l1.maxPriorityFeePerGasCap,
maxFeePerBlobGasCap = configs.l1.maxFeePerBlobGasCap
)
maxFeePerBlobGasCap = configs.l1.maxFeePerBlobGasCap,
),
)
createLineaRollupContractClient(
l1Config = configs.l1,
transactionManager = createTransactionManager(
vertx,
configs.dataSubmissionSigner,
l1Web3jClient
l1Web3jClient,
),
contractGasProvider = primaryOrFallbackGasProvider,
web3jClient = l1Web3jClient,
smartContractErrors = smartContractErrors,
useEthEstimateGas = configs.blobSubmission.useEthEstimateGas
useEthEstimateGas = configs.blobSubmission.useEthEstimateGas,
)
}
private val genesisStateProvider = GenesisStateProvider(
configs.l1.genesisStateRootHash,
configs.l1.genesisShnarfV6
configs.l1.genesisShnarfV6,
)
private val blobCompressionProofCoordinator = run {
@@ -440,14 +440,14 @@ class L1DependentApp(
category = LineaMetricsCategory.BLOB,
name = "proven.highest.block.number",
description = "Highest proven blob compression block number",
measurementSupplier = highestProvenBlobTracker
measurementSupplier = highestProvenBlobTracker,
)
highestProvenBlobTracker
}
val blobCompressionProofHandler: (BlobCompressionProofUpdate) -> SafeFuture<*> = SimpleCompositeSafeFutureHandler(
listOf(
maxProvenBlobCache
)
maxProvenBlobCache,
),
)
val blobCompressionProofCoordinator = BlobCompressionProofCoordinator(
@@ -457,33 +457,33 @@ class L1DependentApp(
rollingBlobShnarfCalculator = RollingBlobShnarfCalculator(
blobShnarfCalculator = GoBackedBlobShnarfCalculator(
version = ShnarfCalculatorVersion.V1_2,
metricsFacade = metricsFacade
metricsFacade = metricsFacade,
),
blobsRepository = blobsRepository,
genesisShnarf = genesisStateProvider.shnarf
genesisShnarf = genesisStateProvider.shnarf,
),
blobZkStateProvider = BlobZkStateProviderImpl(
zkStateClient = zkStateClient
zkStateClient = zkStateClient,
),
config = BlobCompressionProofCoordinator.Config(
pollingInterval = configs.blobCompression.handlerPollingInterval.toKotlinDuration()
pollingInterval = configs.blobCompression.handlerPollingInterval.toKotlinDuration(),
),
blobCompressionProofHandler = blobCompressionProofHandler,
metricsFacade = metricsFacade
metricsFacade = metricsFacade,
)
val highestUnprovenBlobTracker = HighestUnprovenBlobTracker(lastProcessedBlockNumber)
metricsFacade.createGauge(
category = LineaMetricsCategory.BLOB,
name = "unproven.highest.block.number",
description = "Block number of highest unproven blob produced",
measurementSupplier = highestUnprovenBlobTracker
measurementSupplier = highestUnprovenBlobTracker,
)
val compositeSafeFutureHandler = SimpleCompositeSafeFutureHandler(
listOf(
blobCompressionProofCoordinator::handleBlob,
highestUnprovenBlobTracker
)
highestUnprovenBlobTracker,
),
)
conflationCalculator.onBlobCreation(compositeSafeFutureHandler)
blobCompressionProofCoordinator
@@ -494,14 +494,14 @@ class L1DependentApp(
category = LineaMetricsCategory.BLOB,
name = "highest.accepted.block.number",
description = "Highest accepted blob end block number",
measurementSupplier = it
measurementSupplier = it,
)
}
private val alreadySubmittedBlobsFilter =
L1ShnarfBasedAlreadySubmittedBlobsFilter(
lineaRollup = lineaSmartContractClientForDataSubmission,
acceptedBlobEndBlockNumberConsumer = { highestAcceptedBlobTracker(it) }
acceptedBlobEndBlockNumberConsumer = { highestAcceptedBlobTracker(it) },
)
private val latestBlobSubmittedBlockNumberTracker = LatestBlobSubmittedBlockNumberTracker(0UL)
@@ -513,14 +513,14 @@ class L1DependentApp(
category = LineaMetricsCategory.BLOB,
name = "highest.submitted.on.l1",
description = "Highest submitted blob end block number on l1",
measurementSupplier = { latestBlobSubmittedBlockNumberTracker.get() }
measurementSupplier = { latestBlobSubmittedBlockNumberTracker.get() },
)
val blobSubmissionDelayHistogram = metricsFacade.createHistogram(
category = LineaMetricsCategory.BLOB,
name = "submission.delay",
description = "Delay between blob submission and end block timestamps",
baseUnit = "seconds"
baseUnit = "seconds",
)
val blobSubmittedEventConsumers: Map<Consumer<BlobSubmittedEvent>, String> = mapOf(
@@ -529,7 +529,7 @@ class L1DependentApp(
} to "Submitted Blob Tracker Consumer",
Consumer<BlobSubmittedEvent> { blobSubmission ->
blobSubmissionDelayHistogram.record(blobSubmission.getSubmissionDelay().toDouble())
} to "Blob Submission Delay Consumer"
} to "Blob Submission Delay Consumer",
)
BlobSubmissionCoordinator.create(
@@ -537,7 +537,7 @@ class L1DependentApp(
configs.blobSubmission.dbPollingInterval.toKotlinDuration(),
configs.blobSubmission.proofSubmissionDelay.toKotlinDuration(),
configs.blobSubmission.maxBlobsToSubmitPerTick.toUInt(),
configs.blobSubmission.targetBlobsToSendPerTransaction.toUInt()
configs.blobSubmission.targetBlobsToSendPerTransaction.toUInt(),
),
blobsRepository = blobsRepository,
aggregationsRepository = aggregationsRepository,
@@ -546,7 +546,7 @@ class L1DependentApp(
alreadySubmittedBlobsFilter = alreadySubmittedBlobsFilter,
blobSubmittedEventDispatcher = EventDispatcher(blobSubmittedEventConsumers),
vertx = vertx,
clock = Clock.System
clock = Clock.System,
)
}
}
@@ -554,14 +554,14 @@ class L1DependentApp(
private val proofAggregationCoordinatorService: LongRunningService = run {
val maxBlobEndBlockNumberTracker = ConsecutiveProvenBlobsProviderWithLastEndBlockNumberTracker(
aggregationsRepository,
lastProcessedBlockNumber
lastProcessedBlockNumber,
)
metricsFacade.createGauge(
category = LineaMetricsCategory.BLOB,
name = "proven.highest.consecutive.block.number",
description = "Highest consecutive proven blob compression block number",
measurementSupplier = maxBlobEndBlockNumberTracker
measurementSupplier = maxBlobEndBlockNumberTracker,
)
val highestAggregationTracker = HighestULongTracker(lastProcessedBlockNumber)
@@ -569,7 +569,7 @@ class L1DependentApp(
category = LineaMetricsCategory.AGGREGATION,
name = "proven.highest.block.number",
description = "Highest proven aggregation block number",
measurementSupplier = highestAggregationTracker
measurementSupplier = highestAggregationTracker,
)
ProofAggregationCoordinatorService
@@ -581,7 +581,7 @@ class L1DependentApp(
aggregationDeadline = configs.proofAggregation.aggregationDeadline.toKotlinDuration(),
latestBlockProvider = GethCliqueSafeBlockProvider(
l2ExtendedWeb3j.web3jClient,
GethCliqueSafeBlockProvider.Config(configs.l2.blocksToFinalization.toLong())
GethCliqueSafeBlockProvider.Config(configs.l2.blocksToFinalization.toLong()),
),
maxProofsPerAggregation = configs.proofAggregation.aggregationProofsLimit.toUInt(),
startBlockNumberInclusive = lastConsecutiveAggregatedBlockNumber + 1u,
@@ -592,9 +592,9 @@ class L1DependentApp(
l2Web3jClient,
requestRetryConfig = linea.domain.RetryConfig(
backoffDelay = 1.seconds,
failuresWarningThreshold = 3u
failuresWarningThreshold = 3u,
),
vertx = vertx
vertx = vertx,
),
l2MessageService = Web3JL2MessageServiceSmartContractClient.create(
web3jClient = l2Web3jClient,
@@ -605,13 +605,13 @@ class L1DependentApp(
feeHistoryRewardPercentile = configs.l2.feeHistoryRewardPercentile,
transactionManager = l2TransactionManager,
smartContractErrors = smartContractErrors,
smartContractDeploymentBlockNumber = configs.l2.messageServiceDeploymentBlockNumber
smartContractDeploymentBlockNumber = configs.l2.messageServiceDeploymentBlockNumber,
),
aggregationDeadlineDelay = configs.conflation.conflationDeadlineLastBlockConfirmationDelay.toKotlinDuration(),
targetEndBlockNumbers = configs.proofAggregation.targetEndBlocks,
metricsFacade = metricsFacade,
provenAggregationEndBlockNumberConsumer = { highestAggregationTracker(it) },
aggregationSizeMultipleOf = configs.proofAggregation.aggregationSizeMultipleOf.toUInt()
aggregationSizeMultipleOf = configs.proofAggregation.aggregationSizeMultipleOf.toUInt(),
)
}
@@ -636,8 +636,8 @@ class L1DependentApp(
configs.l1.maxPriorityFeePerGasCap.toDouble() *
configs.l1.gasPriceCapMultiplierForFinalization
).toULong(),
maxFeePerBlobGasCap = configs.l1.maxFeePerBlobGasCap
)
maxFeePerBlobGasCap = configs.l1.maxFeePerBlobGasCap,
),
)
val lineaSmartContractClientForFinalization: LineaRollupSmartContractClient = createLineaRollupContractClient(
l1Config = configs.l1,
@@ -645,7 +645,7 @@ class L1DependentApp(
contractGasProvider = primaryOrFallbackGasProvider,
web3jClient = l1Web3jClient,
smartContractErrors = smartContractErrors,
useEthEstimateGas = configs.aggregationFinalization.useEthEstimateGas
useEthEstimateGas = configs.aggregationFinalization.useEthEstimateGas,
)
val latestFinalizationSubmittedBlockNumberTracker = LatestFinalizationSubmittedBlockNumberTracker(0UL)
@@ -653,14 +653,14 @@ class L1DependentApp(
category = LineaMetricsCategory.AGGREGATION,
name = "highest.submitted.on.l1",
description = "Highest submitted finalization end block number on l1",
measurementSupplier = { latestFinalizationSubmittedBlockNumberTracker.get() }
measurementSupplier = { latestFinalizationSubmittedBlockNumberTracker.get() },
)
val finalizationSubmissionDelayHistogram = metricsFacade.createHistogram(
category = LineaMetricsCategory.AGGREGATION,
name = "submission.delay",
description = "Delay between finalization submission and end block timestamps",
baseUnit = "seconds"
baseUnit = "seconds",
)
val submittedFinalizationConsumers: Map<Consumer<FinalizationSubmittedEvent>, String> = mapOf(
@@ -669,13 +669,13 @@ class L1DependentApp(
} to "Finalization Submission Consumer",
Consumer<FinalizationSubmittedEvent> { finalizationSubmission ->
finalizationSubmissionDelayHistogram.record(finalizationSubmission.getSubmissionDelay().toDouble())
} to "Finalization Submission Delay Consumer"
} to "Finalization Submission Delay Consumer",
)
AggregationFinalizationCoordinator.create(
config = AggregationFinalizationCoordinator.Config(
configs.aggregationFinalization.dbPollingInterval.toKotlinDuration(),
configs.aggregationFinalization.proofSubmissionDelay.toKotlinDuration()
configs.aggregationFinalization.proofSubmissionDelay.toKotlinDuration(),
),
aggregationsRepository = aggregationsRepository,
blobsRepository = blobsRepository,
@@ -684,10 +684,10 @@ class L1DependentApp(
aggregationSubmitter = AggregationSubmitterImpl(
lineaRollup = lineaSmartContractClientForFinalization,
gasPriceCapProvider = gasPriceCapProviderForFinalization,
aggregationSubmittedEventConsumer = EventDispatcher(submittedFinalizationConsumers)
aggregationSubmittedEventConsumer = EventDispatcher(submittedFinalizationConsumers),
),
vertx = vertx,
clock = Clock.System
clock = Clock.System,
)
}
}
@@ -702,13 +702,13 @@ class L1DependentApp(
rpcClient = httpJsonRpcClientFactory.createWithLoadBalancing(
endpoints = tracesCounterV2Config.endpoints.toSet(),
maxInflightRequestsPerClient = tracesCounterV2Config.requestLimitPerEndpoint,
log = tracesCountersLog
log = tracesCountersLog,
),
config = TracesGeneratorJsonRpcClientV2.Config(
expectedTracesApiVersion = expectedTracesApiVersionV2
expectedTracesApiVersion = expectedTracesApiVersionV2,
),
retryConfig = tracesCounterV2Config.requestRetryConfig,
log = tracesCountersLog
log = tracesCountersLog,
)
}
@@ -721,13 +721,13 @@ class L1DependentApp(
rpcClient = httpJsonRpcClientFactory.createWithLoadBalancing(
endpoints = tracesConflationConfigV2.endpoints.toSet(),
maxInflightRequestsPerClient = tracesConflationConfigV2.requestLimitPerEndpoint,
log = tracesConflationLog
log = tracesConflationLog,
),
config = TracesGeneratorJsonRpcClientV2.Config(
expectedTracesApiVersion = expectedTracesApiVersionV2
expectedTracesApiVersion = expectedTracesApiVersionV2,
),
retryConfig = tracesConflationConfigV2.requestRetryConfig,
log = tracesConflationLog
log = tracesConflationLog,
)
}
@@ -738,7 +738,7 @@ class L1DependentApp(
category = LineaMetricsCategory.BATCH,
name = "proven.highest.block.number",
description = "Highest proven batch execution block number",
measurementSupplier = highestProvenBatchTracker
measurementSupplier = highestProvenBatchTracker,
)
highestProvenBatchTracker
}
@@ -746,12 +746,12 @@ class L1DependentApp(
val batchProofHandler = SimpleCompositeSafeFutureHandler(
listOf(
maxProvenBatchCache,
BatchProofHandlerImpl(batchesRepository)::acceptNewBatch
)
BatchProofHandlerImpl(batchesRepository)::acceptNewBatch,
),
)
val executionProverClient: ExecutionProverClientV2 = proverClientFactory.executionProverClient(
tracesVersion = configs.traces.rawExecutionTracesVersion,
stateManagerVersion = configs.stateManager.version
stateManagerVersion = configs.stateManager.version,
)
val proofGeneratingConflationHandlerImpl = ProofGeneratingConflationHandlerImpl(
@@ -762,15 +762,15 @@ class L1DependentApp(
web3jClient = l2Web3jClient,
requestRetryConfig = linea.domain.RetryConfig(
backoffDelay = 1.seconds,
failuresWarningThreshold = 3u
failuresWarningThreshold = 3u,
),
vertx = vertx
vertx = vertx,
),
messageServiceAddress = configs.l2.messageServiceAddress
messageServiceAddress = configs.l2.messageServiceAddress,
),
batchProofHandler = batchProofHandler,
vertx = vertx,
config = ProofGeneratingConflationHandlerImpl.Config(5.seconds)
config = ProofGeneratingConflationHandlerImpl.Config(5.seconds),
)
val highestConflationTracker = HighestConflationTracker(lastProcessedBlockNumber)
@@ -778,12 +778,12 @@ class L1DependentApp(
category = LineaMetricsCategory.CONFLATION,
name = "last.block.number",
description = "Last conflated block number",
measurementSupplier = highestConflationTracker
measurementSupplier = highestConflationTracker,
)
val conflationsCounter = metricsFacade.createCounter(
category = LineaMetricsCategory.CONFLATION,
name = "counter",
description = "Counter of new conflations"
description = "Counter of new conflations",
)
SimpleCompositeSafeFutureHandler(
@@ -793,8 +793,8 @@ class L1DependentApp(
{
conflationsCounter.increment()
SafeFuture.COMPLETE
}
)
},
),
)
}
@@ -804,20 +804,20 @@ class L1DependentApp(
conflationService = conflationService,
tracesCountersClient = tracesCountersClient,
vertx = vertx,
encoder = BlockRLPEncoder
encoder = BlockRLPEncoder,
)
}
private val lastProvenBlockNumberProvider = run {
val lastProvenConsecutiveBatchBlockNumberProvider = BatchesRepoBasedLastProvenBlockNumberProvider(
lastProcessedBlockNumber.toLong(),
batchesRepository
batchesRepository,
)
metricsFacade.createGauge(
category = LineaMetricsCategory.BATCH,
name = "proven.highest.consecutive.block.number",
description = "Highest proven consecutive execution batch block number",
measurementSupplier = { lastProvenConsecutiveBatchBlockNumberProvider.getLastKnownProvenBlockNumber() }
measurementSupplier = { lastProvenConsecutiveBatchBlockNumberProvider.getLastKnownProvenBlockNumber() },
)
lastProvenConsecutiveBatchBlockNumberProvider
}
@@ -837,8 +837,8 @@ class L1DependentApp(
// We need to add 1 to l2InclusiveBlockNumberToStopAndFlushAggregation because conflation calculator requires
// block_number = l2InclusiveBlockNumberToStopAndFlushAggregation + 1 to trigger conflation at
// l2InclusiveBlockNumberToStopAndFlushAggregation
lastL2BlockNumberToProcessInclusive = configs.l2InclusiveBlockNumberToStopAndFlushAggregation?.let { it + 1uL }
)
lastL2BlockNumberToProcessInclusive = configs.l2InclusiveBlockNumberToStopAndFlushAggregation?.let { it + 1uL },
),
)
blockCreationMonitor
}
@@ -847,7 +847,7 @@ class L1DependentApp(
val l1BasedLastFinalizedBlockProvider = L1BasedLastFinalizedBlockProvider(
vertx,
lineaRollupClient,
configs.conflation.consistentNumberOfBlocksOnL1ToWait.toUInt()
configs.conflation.consistentNumberOfBlocksOnL1ToWait.toUInt(),
)
return l1BasedLastFinalizedBlockProvider.getLastFinalizedBlock()
}
@@ -867,12 +867,12 @@ class L1DependentApp(
l2HighestBlockTag = configs.messageAnchoring.l2HighestBlockTag,
anchoringTickInterval = configs.messageAnchoring.anchoringTickInterval,
messageQueueCapacity = configs.messageAnchoring.messageQueueCapacity,
maxMessagesToAnchorPerL2Transaction = configs.messageAnchoring.maxMessagesToAnchorPerL2Transaction
maxMessagesToAnchorPerL2Transaction = configs.messageAnchoring.maxMessagesToAnchorPerL2Transaction,
),
l1EthApiClient = createEthApiClient(
web3jClient = l1Web3jClient,
requestRetryConfig = null,
vertx = vertx
vertx = vertx,
),
l2MessageService = Web3JL2MessageServiceSmartContractClient.create(
web3jClient = l2Web3jClient,
@@ -883,8 +883,8 @@ class L1DependentApp(
feeHistoryRewardPercentile = configs.l2.feeHistoryRewardPercentile,
transactionManager = l2TransactionManager,
smartContractErrors = smartContractErrors,
smartContractDeploymentBlockNumber = configs.l2.messageServiceDeploymentBlockNumber
)
smartContractDeploymentBlockNumber = configs.l2.messageServiceDeploymentBlockNumber,
),
)
} else {
DisabledLongRunningService
@@ -897,7 +897,7 @@ class L1DependentApp(
httpJsonRpcClientFactory = httpJsonRpcClientFactory,
l1Web3jClient = l1Web3jClient,
l1Web3jService = l1Web3jService,
config = configs.l2NetworkGasPricingService
config = configs.l2NetworkGasPricingService,
)
} else {
null
@@ -916,16 +916,16 @@ class L1DependentApp(
val l1FeeHistoryWeb3jBlobExtClient = Web3jBlobExtended(
HttpService(
configs.l1DynamicGasPriceCapService.feeHistoryFetcher.endpoint?.toString()
?: configs.l1.ethFeeHistoryEndpoint.toString()
)
?: configs.l1.ethFeeHistoryEndpoint.toString(),
),
)
val l1FeeHistoryFetcher: GasPriceCapFeeHistoryFetcher = GasPriceCapFeeHistoryFetcherImpl(
web3jService = l1FeeHistoryWeb3jBlobExtClient,
config = GasPriceCapFeeHistoryFetcherImpl.Config(
maxBlockCount = configs.l1DynamicGasPriceCapService.feeHistoryFetcher.maxBlockCount,
rewardPercentiles = configs.l1DynamicGasPriceCapService.feeHistoryFetcher.rewardPercentiles
)
rewardPercentiles = configs.l1DynamicGasPriceCapService.feeHistoryFetcher.rewardPercentiles,
),
)
FeeHistoryCachingService(
@@ -939,12 +939,12 @@ class L1DependentApp(
feeHistoryStoragePeriodInBlocks = feeHistoryStoragePeriodInBlocks,
feeHistoryWindowInBlocks = feeHistoryPercentileWindowInBlocks,
numOfBlocksBeforeLatest =
configs.l1DynamicGasPriceCapService.feeHistoryFetcher.numOfBlocksBeforeLatest
configs.l1DynamicGasPriceCapService.feeHistoryFetcher.numOfBlocksBeforeLatest,
),
vertx = vertx,
web3jClient = l1Web3jClient,
feeHistoryFetcher = l1FeeHistoryFetcher,
feeHistoriesRepository = l1FeeHistoriesRepository
feeHistoriesRepository = l1FeeHistoriesRepository,
)
} else {
DisabledLongRunningService
@@ -955,7 +955,7 @@ class L1DependentApp(
category = LineaMetricsCategory.AGGREGATION,
name = "highest.accepted.block.number",
description = "Highest finalized accepted end block number",
measurementSupplier = it
measurementSupplier = it,
)
}
@@ -967,11 +967,11 @@ class L1DependentApp(
"finalized records cleanup" to RecordsCleanupFinalizationHandler(
batchesRepository = batchesRepository,
blobsRepository = blobsRepository,
aggregationsRepository = aggregationsRepository
aggregationsRepository = aggregationsRepository,
),
"highest_accepted_finalization_on_l1" to FinalizationHandler { update: FinalizationMonitor.FinalizationUpdate ->
highestAcceptedFinalizationTracker(update.blockNumber)
}
},
)
.forEach { (handlerName, handler) ->
l1FinalizationMonitor.addFinalizationHandler(handlerName, handler)
@@ -984,7 +984,7 @@ class L1DependentApp(
lastConsecutiveAggregatedBlockNumber = lastConsecutiveAggregatedBlockNumber,
batchesRepository = batchesRepository,
blobsRepository = blobsRepository,
aggregationsRepository = aggregationsRepository
aggregationsRepository = aggregationsRepository,
)
.thenCompose { l1FinalizationMonitor.start() }
.thenCompose { l1FinalizationHandlerForShomeiRpc.start() }
@@ -1016,7 +1016,7 @@ class L1DependentApp(
blockCreationMonitor.stop(),
deadlineConflationCalculatorRunnerOld.stop(),
deadlineConflationCalculatorRunnerNew.stop(),
blobCompressionProofCoordinator.stop()
blobCompressionProofCoordinator.stop(),
)
.thenCompose { SafeFuture.fromRunnable { l1Web3jClient.shutdown() } }
.thenApply { log.info("L1App Stopped") }
@@ -1029,7 +1029,7 @@ class L1DependentApp(
lastConsecutiveAggregatedBlockNumber: ULong,
batchesRepository: BatchesRepository,
blobsRepository: BlobsRepository,
aggregationsRepository: AggregationsRepository
aggregationsRepository: AggregationsRepository,
): SafeFuture<*> {
val blockNumberInclusiveToDeleteFrom = lastProcessedBlockNumber + 1u
val cleanupBatches = batchesRepository.deleteBatchesAfterBlockNumber(blockNumberInclusiveToDeleteFrom.toLong())
@@ -1046,7 +1046,7 @@ class L1DependentApp(
*/
fun resumeConflationFrom(
aggregationsRepository: AggregationsRepository,
lastFinalizedBlock: ULong
lastFinalizedBlock: ULong,
): SafeFuture<ULong> {
return aggregationsRepository
.findConsecutiveProvenBlobs(lastFinalizedBlock.toLong() + 1)
@@ -1061,7 +1061,7 @@ class L1DependentApp(
fun resumeAggregationFrom(
aggregationsRepository: AggregationsRepository,
lastFinalizedBlock: ULong
lastFinalizedBlock: ULong,
): SafeFuture<ULong> {
return aggregationsRepository
.findHighestConsecutiveEndBlockNumber(lastFinalizedBlock.toLong() + 1)
@@ -1075,7 +1075,7 @@ class L1DependentApp(
httpJsonRpcClientFactory: VertxHttpJsonRpcClientFactory,
lineaRollupClient: LineaRollupSmartContractClientReadOnly,
l2Web3jClient: Web3j,
vertx: Vertx
vertx: Vertx,
): LongRunningService {
if (type2StateProofProviderConfig == null ||
type2StateProofProviderConfig.disabled ||
@@ -1091,7 +1091,7 @@ class L1DependentApp(
vertx = vertx,
rpcClient = httpJsonRpcClientFactory.create(it, log = log),
retryConfig = type2StateProofProviderConfig.requestRetryConfig,
log = log
log = log,
)
}
@@ -1103,16 +1103,16 @@ class L1DependentApp(
config =
FinalizationMonitorImpl.Config(
pollingInterval = type2StateProofProviderConfig.l1PollingInterval.toKotlinDuration(),
l1QueryBlockTag = type2StateProofProviderConfig.l1QueryBlockTag
l1QueryBlockTag = type2StateProofProviderConfig.l1QueryBlockTag,
),
contract = lineaRollupClient,
l2Client = l2Web3jClient,
vertx = vertx
vertx = vertx,
)
l1FinalizationMonitor.addFinalizationHandler("type 2 state proof provider finalization updates", {
finalizedBlockNotifier.updateFinalizedBlock(
BlockNumberAndHash(it.blockNumber, it.blockHash.toArray())
BlockNumberAndHash(it.blockNumber, it.blockHash.toArray()),
)
})

View File

@@ -28,12 +28,12 @@ class L2NetworkGasPricingService(
httpJsonRpcClientFactory: VertxHttpJsonRpcClientFactory,
l1Web3jClient: Web3j,
l1Web3jService: Web3jBlobExtended,
config: Config
config: Config,
) : LongRunningService {
data class LegacyGasPricingCalculatorConfig(
val transactionCostCalculatorConfig: TransactionCostCalculator.Config?,
val naiveGasPricingCalculatorConfig: GasUsageRatioWeightedAverageFeesCalculator.Config?,
val legacyGasPricingCalculatorBounds: BoundableFeeCalculator.Config
val legacyGasPricingCalculatorBounds: BoundableFeeCalculator.Config,
)
data class Config(
@@ -46,23 +46,23 @@ class L2NetworkGasPricingService(
val variableFeesCalculatorConfig: VariableFeesCalculator.Config,
val variableFeesCalculatorBounds: BoundableFeeCalculator.Config,
val extraDataCalculatorConfig: MinerExtraDataV1CalculatorImpl.Config,
val extraDataUpdaterConfig: ExtraDataV1UpdaterImpl.Config
val extraDataUpdaterConfig: ExtraDataV1UpdaterImpl.Config,
)
private val log = LogManager.getLogger(this::class.java)
private val gasPricingFeesFetcher: FeesFetcher = FeeHistoryFetcherImpl(
l1Web3jClient,
l1Web3jService,
config.feeHistoryFetcherConfig
config.feeHistoryFetcherConfig,
)
private val boundedVariableCostCalculator = run {
val variableCostCalculator = VariableFeesCalculator(
config.variableFeesCalculatorConfig
config.variableFeesCalculatorConfig,
)
BoundableFeeCalculator(
config = config.variableFeesCalculatorBounds,
feesCalculator = variableCostCalculator
feesCalculator = variableCostCalculator,
)
}
@@ -71,12 +71,12 @@ class L2NetworkGasPricingService(
TransactionCostCalculator(boundedVariableCostCalculator, config.legacy.transactionCostCalculatorConfig)
} else {
GasUsageRatioWeightedAverageFeesCalculator(
config.legacy.naiveGasPricingCalculatorConfig!!
config.legacy.naiveGasPricingCalculatorConfig!!,
)
}
BoundableFeeCalculator(
config.legacy.legacyGasPricingCalculatorBounds,
baseCalculator
baseCalculator,
)
}
@@ -84,7 +84,7 @@ class L2NetworkGasPricingService(
if (config.jsonRpcGasPriceUpdaterConfig != null) {
val l2SetGasPriceUpdater: GasPriceUpdater = GasPriceUpdaterImpl(
httpJsonRpcClientFactory = httpJsonRpcClientFactory,
config = config.jsonRpcGasPriceUpdaterConfig
config = config.jsonRpcGasPriceUpdaterConfig,
)
MinMineableFeesPricerService(
@@ -92,7 +92,7 @@ class L2NetworkGasPricingService(
vertx = vertx,
feesFetcher = gasPricingFeesFetcher,
feesCalculator = legacyGasPricingCalculator,
gasPriceUpdater = l2SetGasPriceUpdater
gasPriceUpdater = l2SetGasPriceUpdater,
)
} else {
null
@@ -106,12 +106,12 @@ class L2NetworkGasPricingService(
minerExtraDataCalculatorImpl = MinerExtraDataV1CalculatorImpl(
config = config.extraDataCalculatorConfig,
variableFeesCalculator = boundedVariableCostCalculator,
legacyFeesCalculator = legacyGasPricingCalculator
legacyFeesCalculator = legacyGasPricingCalculator,
),
extraDataUpdater = ExtraDataV1UpdaterImpl(
httpJsonRpcClientFactory = httpJsonRpcClientFactory,
config = config.extraDataUpdaterConfig
)
config = config.extraDataUpdaterConfig,
),
)
} else {
null
@@ -128,7 +128,7 @@ class L2NetworkGasPricingService(
override fun stop(): CompletableFuture<Unit> {
return SafeFuture.allOf(
minMineableFeesPricerService?.stop() ?: SafeFuture.completedFuture(Unit),
extraDataPricerService?.stop() ?: SafeFuture.completedFuture(Unit)
extraDataPricerService?.stop() ?: SafeFuture.completedFuture(Unit),
)
.thenApply { }
.thenPeek {

View File

@@ -27,7 +27,7 @@ class L1BasedLastFinalizedBlockProvider(
private val lineaRollupSmartContractClient: LineaRollupSmartContractClientReadOnly,
private val consistentNumberOfBlocksOnL1: UInt,
private val numberOfRetries: UInt = Int.MAX_VALUE.toUInt(),
private val pollingInterval: Duration = 2.seconds
private val pollingInterval: Duration = 2.seconds,
) : LastFinalizedBlockProvider {
private val log: Logger = LogManager.getLogger(this::class.java)
@@ -42,7 +42,7 @@ class L1BasedLastFinalizedBlockProvider(
"Rollup finalized block updated from {} to {}, waiting {} blocks for confirmation",
lastObservedBlock.get(),
lastPolledBlockNumber,
consistentNumberOfBlocksOnL1
consistentNumberOfBlocksOnL1,
)
numberOfObservations.set(1)
lastObservedBlock.set(lastPolledBlockNumber)
@@ -54,10 +54,10 @@ class L1BasedLastFinalizedBlockProvider(
vertx,
maxRetries = numberOfRetries.toInt(),
backoffDelay = pollingInterval,
stopRetriesPredicate = isConsistentEnough
stopRetriesPredicate = isConsistentEnough,
) {
lineaRollupSmartContractClient.finalizedL2BlockNumber(
blockParameter = BlockParameter.Tag.LATEST
blockParameter = BlockParameter.Tag.LATEST,
)
}
}

View File

@@ -20,14 +20,14 @@ class BlockParameterDecoder : Decoder<BlockParameter> {
BlockParameter.parse(node.value)
}.fold(
{ it.valid() },
{ ConfigFailure.DecodeError(node, type).invalid() }
{ ConfigFailure.DecodeError(node, type).invalid() },
)
is LongNode -> runCatching {
BlockParameter.fromNumber(node.value)
}.fold(
{ it.valid() },
{ ConfigFailure.DecodeError(node, type).invalid() }
{ ConfigFailure.DecodeError(node, type).invalid() },
)
else -> ConfigFailure.DecodeError(node, type).invalid()

View File

@@ -29,7 +29,7 @@ import kotlin.time.toJavaDuration
import kotlin.time.toKotlinDuration
data class ApiConfig(
val observabilityPort: UInt
val observabilityPort: UInt,
)
data class ConflationConfig(
@@ -42,7 +42,7 @@ data class ConflationConfig(
private var _smartContractErrors: SmartContractErrors?,
val fetchBlocksLimit: Int,
@ConfigAlias("conflation-target-end-block-numbers")
private val _conflationTargetEndBlockNumbers: List<Long> = emptyList()
private val _conflationTargetEndBlockNumbers: List<Long> = emptyList(),
) {
init {
@@ -84,7 +84,7 @@ data class RequestRetryConfigTomlFriendly(
override val maxRetries: Int? = null,
override val timeout: Duration? = null,
override val backoffDelay: Duration = 1.milliseconds.toJavaDuration(),
val failuresWarningThreshold: Int = 0
val failuresWarningThreshold: Int = 0,
) : RetryConfig {
init {
maxRetries?.also {
@@ -105,25 +105,25 @@ data class RequestRetryConfigTomlFriendly(
maxRetries = maxRetries?.toUInt(),
timeout = timeout?.toKotlinDuration(),
backoffDelay = backoffDelay.toKotlinDuration(),
failuresWarningThreshold = failuresWarningThreshold.toUInt()
failuresWarningThreshold = failuresWarningThreshold.toUInt(),
)
internal val asDomain: linea.domain.RetryConfig = linea.domain.RetryConfig(
maxRetries = maxRetries?.toUInt(),
timeout = timeout?.toKotlinDuration(),
backoffDelay = backoffDelay.toKotlinDuration(),
failuresWarningThreshold = failuresWarningThreshold.toUInt()
failuresWarningThreshold = failuresWarningThreshold.toUInt(),
)
companion object {
fun endlessRetry(
backoffDelay: Duration,
failuresWarningThreshold: Int
failuresWarningThreshold: Int,
) = RequestRetryConfigTomlFriendly(
maxRetries = null,
timeout = null,
backoffDelay = backoffDelay,
failuresWarningThreshold = failuresWarningThreshold
failuresWarningThreshold = failuresWarningThreshold,
)
}
}
@@ -131,7 +131,7 @@ data class RequestRetryConfigTomlFriendly(
data class PersistenceRetryConfig(
override val maxRetries: Int? = null,
override val backoffDelay: Duration = 1.seconds.toJavaDuration(),
override val timeout: Duration? = 10.minutes.toJavaDuration()
override val timeout: Duration? = 10.minutes.toJavaDuration(),
) : RetryConfig
internal interface RequestRetryConfigurable {
@@ -144,7 +144,7 @@ data class BlobCompressionConfig(
val blobSizeLimit: Int,
@ConfigAlias("batches-limit")
private val _batchesLimit: Int? = null,
val handlerPollingInterval: Duration
val handlerPollingInterval: Duration,
) {
init {
_batchesLimit?.also {
@@ -163,7 +163,7 @@ data class AggregationConfig(
val deadlineCheckInterval: Duration,
val aggregationSizeMultipleOf: Int = 1,
@ConfigAlias("target-end-blocks")
private val _targetEndBlocks: List<Long> = emptyList()
private val _targetEndBlocks: List<Long> = emptyList(),
) {
val targetEndBlocks: List<ULong> = _targetEndBlocks.map { it.toULong() }
@@ -177,12 +177,12 @@ data class TracesConfig(
val blobCompressorVersion: BlobCompressorVersion,
val expectedTracesApiVersionV2: String,
val countersV2: FunctionalityEndpoint,
val conflationV2: FunctionalityEndpoint
val conflationV2: FunctionalityEndpoint,
) {
data class FunctionalityEndpoint(
val endpoints: List<URL>,
val requestLimitPerEndpoint: UInt,
override val requestRetry: RequestRetryConfigTomlFriendly
override val requestRetry: RequestRetryConfigTomlFriendly,
) : RequestRetryConfigurable {
init {
require(requestLimitPerEndpoint > 0u) { "requestLimitPerEndpoint must be greater than 0" }
@@ -194,7 +194,7 @@ data class StateManagerClientConfig(
val version: String,
val endpoints: List<URL>,
val requestLimitPerEndpoint: UInt,
override val requestRetry: RequestRetryConfigTomlFriendly
override val requestRetry: RequestRetryConfigTomlFriendly,
) : RequestRetryConfigurable {
init {
require(requestLimitPerEndpoint > 0u) { "requestLimitPerEndpoint must be greater than 0" }
@@ -210,7 +210,7 @@ data class BlobSubmissionConfig(
val maxBlobsToSubmitPerTick: Int = maxBlobsToReturn,
val targetBlobsToSendPerTransaction: Int = 9,
val useEthEstimateGas: Boolean = false,
override var disabled: Boolean = false
override var disabled: Boolean = false,
) : FeatureToggleable {
init {
require(maxBlobsToReturn > 0) { "maxBlobsToReturn must be greater than 0" }
@@ -226,7 +226,7 @@ data class AggregationFinalizationConfig(
val maxAggregationsToFinalizePerTick: Int,
val proofSubmissionDelay: Duration,
val useEthEstimateGas: Boolean = false,
override var disabled: Boolean = false
override var disabled: Boolean = false,
) : FeatureToggleable {
init {
require(maxAggregationsToFinalizePerTick > 0) {
@@ -243,7 +243,7 @@ data class DatabaseConfig(
val schema: String,
val readPoolSize: Int,
val readPipeliningLimit: Int,
val transactionalPoolSize: Int
val transactionalPoolSize: Int,
)
data class L1Config(
@@ -268,7 +268,7 @@ data class L1Config(
val blockTime: Duration = Duration.parse("PT12S"),
@ConfigAlias("eth-fee-history-endpoint") private val _ethFeeHistoryEndpoint: URL?,
@ConfigAlias("genesis-state-root-hash") private val _genesisStateRootHash: String,
@ConfigAlias("genesis-shnarf-v6") private val _genesisShnarfV6: String
@ConfigAlias("genesis-shnarf-v6") private val _genesisShnarfV6: String,
) {
val ethFeeHistoryEndpoint: URL
get() = _ethFeeHistoryEndpoint ?: rpcEndpoint
@@ -303,7 +303,7 @@ data class L2Config(
val lastHashSearchWindow: UInt,
val anchoringReceiptPollingInterval: Duration,
val maxReceiptRetries: UInt,
val newBlockPollingInterval: Duration
val newBlockPollingInterval: Duration,
) {
init {
messageServiceAddress.assertIsValidAddress("messageServiceAddress")
@@ -313,11 +313,11 @@ data class L2Config(
data class SignerConfig(
val type: Type,
val web3signer: Web3SignerConfig?,
val web3j: Web3jConfig?
val web3j: Web3jConfig?,
) {
enum class Type {
Web3j,
Web3Signer
Web3Signer,
}
init {
@@ -334,14 +334,14 @@ data class SignerConfig(
}
data class Web3jConfig(
val privateKey: Masked
val privateKey: Masked,
)
data class Web3SignerConfig(
val endpoint: String,
val maxPoolSize: UInt,
val keepAlive: Boolean,
val publicKey: String
val publicKey: String,
)
interface FeatureToggleable {
@@ -354,7 +354,7 @@ data class L1DynamicGasPriceCapServiceConfig(
val gasPriceCapCalculation: GasPriceCapCalculation,
val feeHistoryFetcher: FeeHistoryFetcher,
val feeHistoryStorage: FeeHistoryStorage,
override var disabled: Boolean = false
override var disabled: Boolean = false,
) : FeatureToggleable {
data class GasPriceCapCalculation(
val adjustmentConstant: UInt,
@@ -366,7 +366,7 @@ data class L1DynamicGasPriceCapServiceConfig(
val gasPriceCapsCheckCoefficient: Double,
val historicBaseFeePerBlobGasLowerBound: ULong,
val historicAvgRewardConstant: ULong?,
val timeOfDayMultipliers: TimeOfDayMultipliers?
val timeOfDayMultipliers: TimeOfDayMultipliers?,
) {
init {
timeOfDayMultipliers?.also {
@@ -385,7 +385,7 @@ data class L1DynamicGasPriceCapServiceConfig(
require(timeOfDayMultiplier.value > 0.0) {
throw IllegalStateException(
"Each multiplier in timeOfDayMultipliers must be greater than 0.0." +
" Key=${timeOfDayMultiplier.key} Value=${timeOfDayMultiplier.value}"
" Key=${timeOfDayMultiplier.key} Value=${timeOfDayMultiplier.value}",
)
}
}
@@ -404,7 +404,7 @@ data class L1DynamicGasPriceCapServiceConfig(
}
data class FeeHistoryStorage(
val storagePeriod: Duration
val storagePeriod: Duration,
) {
init {
require(storagePeriod <= MAX_FEE_HISTORIES_STORAGE_PERIOD.toJavaDuration()) {
@@ -418,12 +418,12 @@ data class L1DynamicGasPriceCapServiceConfig(
val maxBlockCount: UInt,
val rewardPercentiles: List<Double>,
val numOfBlocksBeforeLatest: UInt = 4U,
val endpoint: URL?
val endpoint: URL?,
) {
init {
require(
maxBlockCount > 0U &&
maxBlockCount <= MAX_FEE_HISTORY_BLOCK_COUNT
maxBlockCount <= MAX_FEE_HISTORY_BLOCK_COUNT,
) {
"maxBlockCount must be greater than 0 and " +
"less than or equal to $MAX_FEE_HISTORY_BLOCK_COUNT"
@@ -431,7 +431,7 @@ data class L1DynamicGasPriceCapServiceConfig(
require(
rewardPercentiles.isNotEmpty() &&
rewardPercentiles.size <= MAX_REWARD_PERCENTILES_SIZE
rewardPercentiles.size <= MAX_REWARD_PERCENTILES_SIZE,
) {
"rewardPercentiles must be a non-empty list with " +
"maximum length as $MAX_REWARD_PERCENTILES_SIZE."
@@ -459,7 +459,7 @@ data class L1DynamicGasPriceCapServiceConfig(
require(
gasPriceCapCalculation.gasFeePercentileWindow
>= gasPriceCapCalculation.gasFeePercentileWindowLeeway
>= gasPriceCapCalculation.gasFeePercentileWindowLeeway,
) {
"gasFeePercentileWindow must be at least same length as" +
" gasFeePercentileWindowLeeway=${gasPriceCapCalculation.gasFeePercentileWindowLeeway}." +
@@ -483,7 +483,7 @@ data class Type2StateProofProviderConfig(
val endpoints: List<URL>,
val l1QueryBlockTag: BlockParameter.Tag = BlockParameter.Tag.LATEST,
val l1PollingInterval: Duration = Duration.ofSeconds(12),
override val requestRetry: RequestRetryConfigTomlFriendly
override val requestRetry: RequestRetryConfigTomlFriendly,
) : FeatureToggleable, RequestRetryConfigurable
data class TracesLimitsV2ConfigFile(val tracesLimits: Map<TracingModuleV2, UInt>)
@@ -515,7 +515,7 @@ data class CoordinatorConfigTomlDto(
val l2NetworkGasPricing: L2NetworkGasPricingTomlDto,
val l1DynamicGasPriceCapService: L1DynamicGasPriceCapServiceConfig,
val testL1Disabled: Boolean = false,
val prover: ProverConfigTomlDto
val prover: ProverConfigTomlDto,
) {
fun reified(): CoordinatorConfig = CoordinatorConfig(
l2InclusiveBlockNumberToStopAndFlushAggregation = l2InclusiveBlockNumberToStopAndFlushAggregation,
@@ -537,13 +537,13 @@ data class CoordinatorConfigTomlDto(
l2Signer = l2Signer,
messageAnchoring = messageAnchoring.reified(
l1DefaultEndpoint = l1.rpcEndpoint,
l2DefaultEndpoint = l2.rpcEndpoint
l2DefaultEndpoint = l2.rpcEndpoint,
),
l2NetworkGasPricingService =
if (testL1Disabled || l2NetworkGasPricing.disabled) null else l2NetworkGasPricing.reified(),
l1DynamicGasPriceCapService = l1DynamicGasPriceCapService,
testL1Disabled = testL1Disabled,
proversConfig = prover.reified()
proversConfig = prover.reified(),
)
}
@@ -569,7 +569,7 @@ data class CoordinatorConfig(
val l2NetworkGasPricingService: L2NetworkGasPricingService.Config?,
val l1DynamicGasPriceCapService: L1DynamicGasPriceCapServiceConfig,
val testL1Disabled: Boolean = false,
val proversConfig: ProversConfig
val proversConfig: ProversConfig,
) {
init {
if (l2InclusiveBlockNumberToStopAndFlushAggregation != null) {
@@ -583,7 +583,7 @@ data class CoordinatorConfig(
require(
blobCompression.batchesLimit == null ||
blobCompression.batchesLimit!! < proofAggregation.aggregationProofsLimit.toUInt()
blobCompression.batchesLimit!! < proofAggregation.aggregationProofsLimit.toUInt(),
) {
"[blob-compression].batchesLimit=${blobCompression.batchesLimit} must be less than " +
"[proof-aggregation].aggregationProofsLimit=${proofAggregation.aggregationProofsLimit}"

View File

@@ -19,7 +19,7 @@ import kotlin.time.toKotlinDuration
data class SampleTransactionGasPricingTomlDto(
val plainTransferCostMultiplier: Double = 1.0,
val compressedTxSize: Int = 125,
val expectedGas: Int = 21000
val expectedGas: Int = 21000,
)
data class LegacyGasPricingTomlDto(
@@ -28,11 +28,11 @@ data class LegacyGasPricingTomlDto(
val naiveGasPricing: NaiveGasPricingTomlDto?,
val sampleTransactionGasPricing: SampleTransactionGasPricingTomlDto = SampleTransactionGasPricingTomlDto(),
val gasPriceUpperBound: ULong,
val gasPriceLowerBound: ULong
val gasPriceLowerBound: ULong,
) {
enum class Type {
Naive,
SampleTransaction
SampleTransaction,
}
init {
@@ -49,7 +49,7 @@ data class LegacyGasPricingTomlDto(
data class NaiveGasPricingTomlDto(
val baseFeeCoefficient: Double,
val priorityFeeCoefficient: Double,
val baseFeeBlobCoefficient: Double
val baseFeeBlobCoefficient: Double,
)
data class VariableCostPricingTomlDto(
@@ -57,7 +57,7 @@ data class VariableCostPricingTomlDto(
val legacyFeesMultiplier: Double,
val margin: Double,
val variableCostUpperBound: ULong,
val variableCostLowerBound: ULong
val variableCostLowerBound: ULong,
) {
init {
require(variableCostUpperBound >= variableCostLowerBound) {
@@ -69,7 +69,7 @@ data class VariableCostPricingTomlDto(
data class JsonRpcPricingPropagationTomlDto(
override var disabled: Boolean = false,
val gethGasPriceUpdateRecipients: List<URL>,
val besuGasPriceUpdateRecipients: List<URL>
val besuGasPriceUpdateRecipients: List<URL>,
) : FeatureToggleable {
init {
require(disabled || (gethGasPriceUpdateRecipients.isNotEmpty() || besuGasPriceUpdateRecipients.isNotEmpty())) {
@@ -81,7 +81,7 @@ data class JsonRpcPricingPropagationTomlDto(
data class ExtraDataPricingPropagationTomlDto(
override var disabled: Boolean = false,
val extraDataUpdateRecipient: URL
val extraDataUpdateRecipient: URL,
) : FeatureToggleable
data class L2NetworkGasPricingTomlDto(
@@ -99,7 +99,7 @@ data class L2NetworkGasPricingTomlDto(
val legacy: LegacyGasPricingTomlDto,
val variableCostPricing: VariableCostPricingTomlDto,
val jsonRpcPricingPropagation: JsonRpcPricingPropagationTomlDto?,
val extraDataPricingPropagation: ExtraDataPricingPropagationTomlDto
val extraDataPricingPropagation: ExtraDataPricingPropagationTomlDto,
) : FeatureToggleable, RequestRetryConfigurable {
init {
require(feeHistoryBlockCount > 0) { "feeHistoryBlockCount must be greater than 0" }
@@ -124,13 +124,13 @@ data class L2NetworkGasPricingTomlDto(
priorityFeeCoefficient = legacy.naiveGasPricing.priorityFeeCoefficient,
baseFeeBlobCoefficient = legacy.naiveGasPricing.baseFeeBlobCoefficient,
blobSubmissionExpectedExecutionGas = blobSubmissionExpectedExecutionGas,
expectedBlobGas = l1BlobGas
expectedBlobGas = l1BlobGas,
),
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
legacy.gasPriceUpperBound.toDouble(),
legacy.gasPriceLowerBound.toDouble(),
0.0
)
0.0,
),
)
}
@@ -140,14 +140,14 @@ data class L2NetworkGasPricingTomlDto(
sampleTransactionCostMultiplier = legacy.sampleTransactionGasPricing.plainTransferCostMultiplier,
fixedCostWei = variableCostPricing.gasPriceFixedCost,
compressedTxSize = legacy.sampleTransactionGasPricing.compressedTxSize,
expectedGas = legacy.sampleTransactionGasPricing.expectedGas
expectedGas = legacy.sampleTransactionGasPricing.expectedGas,
),
naiveGasPricingCalculatorConfig = null,
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
legacy.gasPriceUpperBound.toDouble(),
legacy.gasPriceLowerBound.toDouble(),
0.0
)
0.0,
),
)
}
}
@@ -155,7 +155,7 @@ data class L2NetworkGasPricingTomlDto(
GasPriceUpdaterImpl.Config(
gethEndpoints = jsonRpcPricingPropagation.gethGasPriceUpdateRecipients,
besuEndPoints = jsonRpcPricingPropagation.besuGasPriceUpdateRecipients,
retryConfig = requestRetryConfig
retryConfig = requestRetryConfig,
)
} else {
null
@@ -163,7 +163,7 @@ data class L2NetworkGasPricingTomlDto(
return L2NetworkGasPricingService.Config(
feeHistoryFetcherConfig = FeeHistoryFetcherImpl.Config(
feeHistoryBlockCount = feeHistoryBlockCount.toUInt(),
feeHistoryRewardPercentile = feeHistoryRewardPercentile
feeHistoryRewardPercentile = feeHistoryRewardPercentile,
),
legacy = legacyGasPricingConfig,
jsonRpcGasPriceUpdaterConfig = gasPriceUpdaterConfig,
@@ -174,21 +174,21 @@ data class L2NetworkGasPricingTomlDto(
blobSubmissionExpectedExecutionGas = blobSubmissionExpectedExecutionGas.toUInt(),
bytesPerDataSubmission = l1BlobGas.toUInt(),
expectedBlobGas = bytesPerDataSubmission.toUInt(),
margin = variableCostPricing.margin
margin = variableCostPricing.margin,
),
variableFeesCalculatorBounds = BoundableFeeCalculator.Config(
feeUpperBound = variableCostPricing.variableCostUpperBound.toDouble(),
feeLowerBound = variableCostPricing.variableCostLowerBound.toDouble(),
feeMargin = 0.0
feeMargin = 0.0,
),
extraDataCalculatorConfig = MinerExtraDataV1CalculatorImpl.Config(
fixedCostInKWei = variableCostPricing.gasPriceFixedCost.toKWeiUInt(),
ethGasPriceMultiplier = variableCostPricing.legacyFeesMultiplier
ethGasPriceMultiplier = variableCostPricing.legacyFeesMultiplier,
),
extraDataUpdaterConfig = ExtraDataV1UpdaterImpl.Config(
extraDataPricingPropagation.extraDataUpdateRecipient,
requestRetryConfig
)
requestRetryConfig,
),
)
}
}

View File

@@ -14,7 +14,7 @@ data class MessageAnchoringConfigTomlDto(
val l1HighestBlockTag: BlockParameter = BlockParameter.Tag.FINALIZED,
val l1RequestRetries: RequestRetryConfigTomlFriendly = RequestRetryConfigTomlFriendly.endlessRetry(
backoffDelay = 1.seconds.toJavaDuration(),
failuresWarningThreshold = 3
failuresWarningThreshold = 3,
),
val l1EventPollingInterval: Duration = 12.seconds.toJavaDuration(),
val l1EventPollingTimeout: Duration = 6.seconds.toJavaDuration(),
@@ -24,11 +24,11 @@ data class MessageAnchoringConfigTomlDto(
val l2HighestBlockTag: BlockParameter = BlockParameter.Tag.LATEST,
val l2RequestRetries: RequestRetryConfigTomlFriendly = RequestRetryConfigTomlFriendly.endlessRetry(
backoffDelay = 1.seconds.toJavaDuration(),
failuresWarningThreshold = 3
failuresWarningThreshold = 3,
),
val anchoringTickInterval: Duration = 2.seconds.toJavaDuration(),
val messageQueueCapacity: Int = 10_000,
val maxMessagesToAnchorPerL2Transaction: Int = 100
val maxMessagesToAnchorPerL2Transaction: Int = 100,
) {
init {
require(messageQueueCapacity > 0) {
@@ -56,7 +56,7 @@ data class MessageAnchoringConfigTomlDto(
fun reified(
l1DefaultEndpoint: URL,
l2DefaultEndpoint: URL
l2DefaultEndpoint: URL,
): MessageAnchoringConfig {
return MessageAnchoringConfig(
disabled = disabled,
@@ -72,7 +72,7 @@ data class MessageAnchoringConfigTomlDto(
l1EventSearchBlockChunk = l1EventSearchBlockChunk.toUInt(),
anchoringTickInterval = anchoringTickInterval.toKotlinDuration(),
messageQueueCapacity = messageQueueCapacity.toUInt(),
maxMessagesToAnchorPerL2Transaction = maxMessagesToAnchorPerL2Transaction.toUInt()
maxMessagesToAnchorPerL2Transaction = maxMessagesToAnchorPerL2Transaction.toUInt(),
)
}
}
@@ -91,5 +91,5 @@ data class MessageAnchoringConfig(
val l1EventSearchBlockChunk: UInt,
val anchoringTickInterval: kotlin.time.Duration,
val messageQueueCapacity: UInt,
val maxMessagesToAnchorPerL2Transaction: UInt
val maxMessagesToAnchorPerL2Transaction: UInt,
) : FeatureToggleable

View File

@@ -19,13 +19,13 @@ data class ProverConfigTomlDto(
val execution: FileSystemTomlDto,
val blobCompression: FileSystemTomlDto,
val proofAggregation: FileSystemTomlDto,
val new: ProverConfigTomlDto? = null
val new: ProverConfigTomlDto? = null,
) {
private fun asProverConfig(): ProverConfig {
return ProverConfig(
execution = execution.toDomain(),
blobCompression = blobCompression.toDomain(),
proofAggregation = proofAggregation.toDomain()
proofAggregation = proofAggregation.toDomain(),
)
}
@@ -56,7 +56,7 @@ data class ProverConfigTomlDto(
return ProversConfig(
proverA = this.asProverConfig(),
switchBlockNumberInclusive = new?.switchBlockNumberInclusive?.toULong(),
proverB = new?.asProverConfig()
proverB = new?.asProverConfig(),
)
}
}
@@ -67,7 +67,7 @@ data class FileSystemTomlDto(
internal var fsInprogressRequestWritingSuffix: String?,
internal var fsInprogressProvingSuffixPattern: String?,
internal var fsPollingInterval: Duration?,
internal var fsPollingTimeout: Duration?
internal var fsPollingTimeout: Duration?,
) {
internal fun reifyWithRootDefaults(rootConfig: ProverConfigTomlDto) {
fsInprogressRequestWritingSuffix = fsInprogressRequestWritingSuffix
@@ -85,7 +85,7 @@ data class FileSystemTomlDto(
inprogressRequestWritingSuffix = fsInprogressRequestWritingSuffix!!,
inprogressProvingSuffixPattern = fsInprogressProvingSuffixPattern!!,
pollingInterval = fsPollingInterval!!.toKotlinDuration(),
pollingTimeout = fsPollingTimeout!!.toKotlinDuration()
pollingTimeout = fsPollingTimeout!!.toKotlinDuration(),
)
}
}

View File

@@ -25,18 +25,18 @@ class BlockCreationMonitor(
private val blockCreationListener: BlockCreationListener,
private val lastProvenBlockNumberProviderAsync: LastProvenBlockNumberProviderAsync,
private val config: Config,
private val log: Logger = LogManager.getLogger(BlockCreationMonitor::class.java)
private val log: Logger = LogManager.getLogger(BlockCreationMonitor::class.java),
) : PeriodicPollingService(
vertx = vertx,
pollingIntervalMs = config.pollingInterval.inWholeMilliseconds,
log = log
log = log,
) {
data class Config(
val pollingInterval: Duration,
val blocksToFinalization: Long,
val blocksFetchLimit: Long,
val startingBlockWaitTimeout: Duration = 14.days,
val lastL2BlockNumberToProcessInclusive: ULong? = null
val lastL2BlockNumberToProcessInclusive: ULong? = null,
)
private val _nexBlockNumberToFetch: AtomicLong = AtomicLong(startingBlockNumberExclusive + 1)
@@ -76,7 +76,7 @@ class BlockCreationMonitor(
log.warn(
"Block {} not found yet. Retrying in {}",
startingBlockNumberExclusive,
config.pollingInterval
config.pollingInterval,
)
false
} else {
@@ -84,7 +84,7 @@ class BlockCreationMonitor(
expectedParentBlockHash.set(block.hash)
true
}
}
},
) {
web3j.ethGetBlock(startingBlockNumberExclusive.toBlockParameter())
}
@@ -104,7 +104,7 @@ class BlockCreationMonitor(
lastProvenBlockNumber,
_nexBlockNumberToFetch.get(),
_nexBlockNumberToFetch.get() - lastProvenBlockNumber,
config.blocksFetchLimit
config.blocksFetchLimit,
)
SafeFuture.COMPLETE
} else if (config.lastL2BlockNumberToProcessInclusive != null &&
@@ -115,7 +115,7 @@ class BlockCreationMonitor(
"All blocks upto and including lastL2BlockNumberInclusiveToProcess={} have been processed. " +
"nextBlockNumberToFetch={}",
config.lastL2BlockNumberToProcessInclusive,
nexBlockNumberToFetch
nexBlockNumberToFetch,
)
SafeFuture.COMPLETE
} else {
@@ -128,7 +128,7 @@ class BlockCreationMonitor(
log.debug(
"updating nexBlockNumberToFetch from {} --> {}",
_nexBlockNumberToFetch.get(),
_nexBlockNumberToFetch.incrementAndGet()
_nexBlockNumberToFetch.incrementAndGet(),
)
expectedParentBlockHash.set(block.hash)
}
@@ -140,7 +140,7 @@ class BlockCreationMonitor(
block.number,
block.hash.encodeHex(),
block.parentHash.encodeHex(),
expectedParentBlockHash.get().encodeHex()
expectedParentBlockHash.get().encodeHex(),
)
SafeFuture.failedFuture(IllegalStateException("Reorg detected on block ${block.number}"))
}
@@ -164,7 +164,7 @@ class BlockCreationMonitor(
.thenApply {
log.debug(
"blockCreationListener blockNumber={} resolved with success",
payload.number
payload.number,
)
}
.whenException { throwable ->
@@ -172,7 +172,7 @@ class BlockCreationMonitor(
"Failed to notify blockCreationListener: blockNumber={} errorMessage={}",
payload.number,
throwable.message,
throwable
throwable,
)
}
}
@@ -195,7 +195,7 @@ class BlockCreationMonitor(
"eth_getBlockByNumber({}) failed: errorMessage={}",
blockNumber,
it.message,
it
it,
)
}
} else {

View File

@@ -12,10 +12,10 @@ import tech.pegasys.teku.infrastructure.async.SafeFuture
class GethCliqueSafeBlockProvider(
private val web3j: Web3j,
private val config: Config
private val config: Config,
) : SafeBlockProvider {
data class Config(
val blocksToFinalization: Long
val blocksToFinalization: Long,
)
override fun getLatestSafeBlock(): SafeFuture<Block> {

View File

@@ -15,7 +15,7 @@ interface LastProvenBlockNumberProviderSync {
class BatchesRepoBasedLastProvenBlockNumberProvider(
startingBlockNumberExclusive: Long,
private val batchesRepository: BatchesRepository
private val batchesRepository: BatchesRepository,
) : LastProvenBlockNumberProviderAsync, LastProvenBlockNumberProviderSync {
private var latestL1FinalizedBlock: AtomicLong = AtomicLong(startingBlockNumberExclusive)
private var lastProvenBlock: AtomicLong = AtomicLong(startingBlockNumberExclusive)
@@ -35,7 +35,7 @@ class BatchesRepoBasedLastProvenBlockNumberProvider(
private fun findAndCacheLastProvenBlockNumberFromDb(): SafeFuture<Long> {
return batchesRepository.findHighestConsecutiveEndBlockNumberFromBlockNumber(
latestL1FinalizedBlock.get() + 1
latestL1FinalizedBlock.get() + 1,
).thenApply {
newValue ->
if (newValue != null) {

View File

@@ -3,7 +3,7 @@ package net.consensys.zkevm.ethereum.coordination
import tech.pegasys.teku.infrastructure.async.SafeFuture
class SimpleCompositeSafeFutureHandler<T>(
private val handlers: List<(T) -> SafeFuture<*>>
private val handlers: List<(T) -> SafeFuture<*>>,
) : (T) -> SafeFuture<*> {
override fun invoke(arg: T): SafeFuture<Unit> {
val handlingFutures =

View File

@@ -8,7 +8,7 @@ import java.util.function.Supplier
class ConsecutiveProvenBlobsProviderWithLastEndBlockNumberTracker(
private val repository: AggregationsRepository,
initialBlockNumber: ULong
initialBlockNumber: ULong,
) : ConsecutiveProvenBlobsProvider, Supplier<Number> {
private val cache = AtomicReference(initialBlockNumber)

View File

@@ -6,7 +6,7 @@ import linea.domain.BlockInterval
import tech.pegasys.teku.infrastructure.async.SafeFuture
class BlobZkStateProviderImpl(
private val zkStateClient: StateManagerClientV1
private val zkStateClient: StateManagerClientV1,
) : BlobZkStateProvider {
override fun getBlobZKState(blockRange: ULongRange): SafeFuture<BlobZkState> {
return zkStateClient
@@ -14,7 +14,7 @@ class BlobZkStateProviderImpl(
.thenApply {
BlobZkState(
parentStateRootHash = it.zkParentStateRootHash,
finalStateRootHash = it.zkEndStateRootHash
finalStateRootHash = it.zkEndStateRootHash,
)
}
}

View File

@@ -17,7 +17,7 @@ class ForkChoiceUpdaterImpl(private val rollupForkChoiceUpdatedClients: List<Rol
log.debug(
"Updating finalized block: {}, to {} clients",
finalizedBlockNumberAndHash,
rollupForkChoiceUpdatedClients.size
rollupForkChoiceUpdatedClients.size,
)
val futures: List<SafeFuture<*>> = rollupForkChoiceUpdatedClients.map { rollupForkChoiceUpdatedClient ->
rollupForkChoiceUpdatedClient

View File

@@ -28,7 +28,7 @@ class L1BasedLastFinalizedBlockProviderTest {
whenever(lineaRollupClient.finalizedL2BlockNumber(eq(BlockParameter.Tag.LATEST)))
.thenReturn(
SafeFuture.completedFuture(replies[0]),
*replies.subList(1, replies.size).map { SafeFuture.completedFuture(it) }.toTypedArray()
*replies.subList(1, replies.size).map { SafeFuture.completedFuture(it) }.toTypedArray(),
)
val resumerCalculator = L1BasedLastFinalizedBlockProvider(
@@ -36,7 +36,7 @@ class L1BasedLastFinalizedBlockProviderTest {
lineaRollupClient,
consistentNumberOfBlocksOnL1 = 3u,
numberOfRetries = 50u,
pollingInterval = 10.milliseconds
pollingInterval = 10.milliseconds,
)
assertThat(resumerCalculator.getLastFinalizedBlock().get()).isEqualTo(101.toULong())

View File

@@ -23,7 +23,7 @@ class L1DependentAppTest {
val lastProcessedBlock =
L1DependentApp.resumeConflationFrom(
aggregationsRepository,
lastFinalizedBlock
lastFinalizedBlock,
).get()
assertThat(lastProcessedBlock).isEqualTo(lastFinalizedBlock)
verify(aggregationsRepository).findConsecutiveProvenBlobs(lastFinalizedBlock.toLong() + 1)
@@ -49,12 +49,12 @@ class L1DependentAppTest {
lastConsecutiveAggregatedBlockNumber = lastConsecutiveAggregatedBlockNumber,
batchesRepository = batchesRepository,
blobsRepository = blobsRepository,
aggregationsRepository = aggregationsRepository
aggregationsRepository = aggregationsRepository,
).get()
verify(batchesRepository).deleteBatchesAfterBlockNumber((lastProcessedBlock + 1uL).toLong())
verify(blobsRepository).deleteBlobsAfterBlockNumber(lastProcessedBlock + 1uL)
verify(aggregationsRepository).deleteAggregationsAfterBlockNumber(
(lastConsecutiveAggregatedBlockNumber + 1uL).toLong()
(lastConsecutiveAggregatedBlockNumber + 1uL).toLong(),
)
}
}

View File

@@ -45,9 +45,9 @@ class CoordinatorConfigTest {
_smartContractErrors = mapOf(
// L1 Linea Rollup
"0f06cd15" to "DataAlreadySubmitted",
"c01eab56" to "EmptySubmissionData"
"c01eab56" to "EmptySubmissionData",
),
fetchBlocksLimit = 4000
fetchBlocksLimit = 4000,
)
private val proversConfig = ProversConfig(
@@ -58,7 +58,7 @@ class CoordinatorConfigTest {
pollingInterval = 1.seconds,
pollingTimeout = 10.minutes,
inprogressProvingSuffixPattern = ".*\\.inprogress\\.prover.*",
inprogressRequestWritingSuffix = ".inprogress_coordinator_writing"
inprogressRequestWritingSuffix = ".inprogress_coordinator_writing",
),
blobCompression = FileBasedProverConfig(
requestsDirectory = Path.of("/data/prover/v2/compression/requests"),
@@ -66,7 +66,7 @@ class CoordinatorConfigTest {
pollingInterval = 1.seconds,
pollingTimeout = 10.minutes,
inprogressProvingSuffixPattern = ".*\\.inprogress\\.prover.*",
inprogressRequestWritingSuffix = ".inprogress_coordinator_writing"
inprogressRequestWritingSuffix = ".inprogress_coordinator_writing",
),
proofAggregation = FileBasedProverConfig(
requestsDirectory = Path.of("/data/prover/v2/aggregation/requests"),
@@ -74,24 +74,24 @@ class CoordinatorConfigTest {
pollingInterval = 1.seconds,
pollingTimeout = 10.minutes,
inprogressProvingSuffixPattern = ".*\\.inprogress\\.prover.*",
inprogressRequestWritingSuffix = ".inprogress_coordinator_writing"
)
inprogressRequestWritingSuffix = ".inprogress_coordinator_writing",
),
),
switchBlockNumberInclusive = null,
proverB = null
proverB = null,
)
private val blobCompressionConfig = BlobCompressionConfig(
blobSizeLimit = 100 * 1024,
handlerPollingInterval = Duration.parse("PT1S"),
_batchesLimit = 1
_batchesLimit = 1,
)
private val aggregationConfig = AggregationConfig(
aggregationProofsLimit = 3,
aggregationDeadline = Duration.parse("PT10S"),
aggregationCoordinatorPollingInterval = Duration.parse("PT2S"),
deadlineCheckInterval = Duration.parse("PT8S")
deadlineCheckInterval = Duration.parse("PT8S"),
)
private val tracesConfig = TracesConfig(
@@ -103,38 +103,38 @@ class CoordinatorConfigTest {
requestLimitPerEndpoint = 1U,
requestRetry = RequestRetryConfigTomlFriendly(
backoffDelay = Duration.parse("PT1S"),
failuresWarningThreshold = 2
)
failuresWarningThreshold = 2,
),
),
countersV2 = TracesConfig.FunctionalityEndpoint(
endpoints = listOf(URI("http://traces-node:8545/").toURL()),
requestLimitPerEndpoint = 1U,
requestRetry = RequestRetryConfigTomlFriendly(
backoffDelay = Duration.parse("PT1S"),
failuresWarningThreshold = 2
)
)
failuresWarningThreshold = 2,
),
),
)
private val type2StateProofProviderConfig = Type2StateProofProviderConfig(
endpoints = listOf(URI("http://shomei-frontend:8888/").toURL()),
requestRetry = RequestRetryConfigTomlFriendly(
backoffDelay = Duration.parse("PT1S"),
failuresWarningThreshold = 2
failuresWarningThreshold = 2,
),
l1QueryBlockTag = BlockParameter.Tag.SAFE,
l1PollingInterval = Duration.parse("PT6S")
l1PollingInterval = Duration.parse("PT6S"),
)
private val stateManagerConfig = StateManagerClientConfig(
version = "2.3.0",
endpoints = listOf(
URI("http://shomei:8888/").toURL()
URI("http://shomei:8888/").toURL(),
),
requestLimitPerEndpoint = 2U,
requestRetry = RequestRetryConfigTomlFriendly(
backoffDelay = Duration.parse("PT2S"),
failuresWarningThreshold = 2
)
failuresWarningThreshold = 2,
),
)
private val blobSubmissionConfig = BlobSubmissionConfig(
@@ -146,7 +146,7 @@ class CoordinatorConfigTest {
proofSubmissionDelay = Duration.parse("PT1S"),
targetBlobsToSendPerTransaction = 9,
useEthEstimateGas = false,
disabled = false
disabled = false,
)
private val aggregationFinalizationConfig = AggregationFinalizationConfig(
@@ -154,7 +154,7 @@ class CoordinatorConfigTest {
maxAggregationsToFinalizePerTick = 1,
proofSubmissionDelay = Duration.parse("PT1S"),
useEthEstimateGas = true,
disabled = false
disabled = false,
)
private val databaseConfig = DatabaseConfig(
@@ -165,12 +165,12 @@ class CoordinatorConfigTest {
schema = "linea_coordinator",
readPoolSize = 10,
readPipeliningLimit = 10,
transactionalPoolSize = 10
transactionalPoolSize = 10,
)
private val persistenceRetryConfig = PersistenceRetryConfig(
maxRetries = null,
backoffDelay = Duration.parse("PT1S")
backoffDelay = Duration.parse("PT1S"),
)
private val l1Config = L1Config(
@@ -194,7 +194,7 @@ class CoordinatorConfigTest {
blockRangeLoopLimit = 500U,
_ethFeeHistoryEndpoint = null,
_genesisStateRootHash = "0x072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd",
_genesisShnarfV6 = "0x47452a1b9ebadfe02bdd02f580fa1eba17680d57eec968a591644d05d78ee84f"
_genesisShnarfV6 = "0x47452a1b9ebadfe02bdd02f580fa1eba17680d57eec968a591644d05d78ee84f",
)
private val l2Config = L2Config(
@@ -208,7 +208,7 @@ class CoordinatorConfigTest {
lastHashSearchWindow = 25U,
anchoringReceiptPollingInterval = Duration.parse("PT01S"),
maxReceiptRetries = 120U,
newBlockPollingInterval = Duration.parse("PT1S")
newBlockPollingInterval = Duration.parse("PT1S"),
)
private val finalizationSigner = SignerConfig(
@@ -219,9 +219,9 @@ class CoordinatorConfigTest {
keepAlive = true,
publicKey =
"ba5734d8f7091719471e7f7ed6b9df170dc70cc661ca05e688601ad984f068b0d67351e5f06073092499336ab0839ef8a521afd334e5" +
"3807205fa2f08eec74f4"
"3807205fa2f08eec74f4",
),
web3j = Web3jConfig(Masked("0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"))
web3j = Web3jConfig(Masked("0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d")),
)
private val dataSubmissionSigner = SignerConfig(
@@ -232,9 +232,9 @@ class CoordinatorConfigTest {
keepAlive = true,
publicKey =
"9d9031e97dd78ff8c15aa86939de9b1e791066a0224e331bc962a2099a7b1f0464b8bbafe1535f2301c72c2cb3535b172da30b02686a" +
"b0393d348614f157fbdb"
"b0393d348614f157fbdb",
),
web3j = Web3jConfig(Masked("0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a"))
web3j = Web3jConfig(Masked("0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a")),
)
private val l2SignerConfig = SignerConfig(
type = SignerConfig.Type.Web3j,
@@ -244,43 +244,43 @@ class CoordinatorConfigTest {
keepAlive = true,
publicKey =
"4a788ad6fa008beed58de6418369717d7492f37d173d70e2c26d9737e2c6eeae929452ef8602a19410844db3e200a0e73f5208fd7625" +
"9a8766b73953fc3e7023"
"9a8766b73953fc3e7023",
),
web3j = Web3jConfig(Masked("0x4d01ae6487860981699236a58b68f807ee5f17b12df5740b85cf4c4653be0f55"))
web3j = Web3jConfig(Masked("0x4d01ae6487860981699236a58b68f807ee5f17b12df5740b85cf4c4653be0f55")),
)
private val l2NetworkGasPricingRequestRetryConfig = RequestRetryConfig(
maxRetries = 3u,
timeout = 6.seconds,
backoffDelay = 1.seconds,
failuresWarningThreshold = 2u
failuresWarningThreshold = 2u,
)
private val l2NetworkGasPricingServiceConfig = L2NetworkGasPricingService.Config(
feeHistoryFetcherConfig = FeeHistoryFetcherImpl.Config(
feeHistoryBlockCount = 50U,
feeHistoryRewardPercentile = 15.0
feeHistoryRewardPercentile = 15.0,
),
legacy = L2NetworkGasPricingService.LegacyGasPricingCalculatorConfig(
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
feeUpperBound = 10_000_000_000.0,
feeLowerBound = 90_000_000.0,
feeMargin = 0.0
feeMargin = 0.0,
),
transactionCostCalculatorConfig = TransactionCostCalculator.Config(
sampleTransactionCostMultiplier = 1.0,
fixedCostWei = 3000000u,
compressedTxSize = 125,
expectedGas = 21000
expectedGas = 21000,
),
naiveGasPricingCalculatorConfig = null
naiveGasPricingCalculatorConfig = null,
),
jsonRpcGasPriceUpdaterConfig = GasPriceUpdaterImpl.Config(
gethEndpoints = listOf(
URI("http://l2-node:8545/").toURL()
URI("http://l2-node:8545/").toURL(),
),
besuEndPoints = listOf(),
retryConfig = l2NetworkGasPricingRequestRetryConfig
retryConfig = l2NetworkGasPricingRequestRetryConfig,
),
jsonRpcPriceUpdateInterval = 12.seconds,
extraDataPricingPropagationEnabled = true,
@@ -289,21 +289,21 @@ class CoordinatorConfigTest {
blobSubmissionExpectedExecutionGas = 213_000u,
bytesPerDataSubmission = 131072u,
expectedBlobGas = 131072u,
margin = 4.0
margin = 4.0,
),
variableFeesCalculatorBounds = BoundableFeeCalculator.Config(
feeUpperBound = 10_000_000_001.0,
feeLowerBound = 90_000_001.0,
feeMargin = 0.0
feeMargin = 0.0,
),
extraDataCalculatorConfig = MinerExtraDataV1CalculatorImpl.Config(
fixedCostInKWei = 3000u,
ethGasPriceMultiplier = 1.2
ethGasPriceMultiplier = 1.2,
),
extraDataUpdaterConfig = ExtraDataV1UpdaterImpl.Config(
sequencerEndpoint = URI(/* str = */ "http://sequencer:8545/").toURL(),
retryConfig = l2NetworkGasPricingRequestRetryConfig
)
sequencerEndpoint = URI("http://sequencer:8545/").toURL(),
retryConfig = l2NetworkGasPricingRequestRetryConfig,
),
)
private val l1DynamicGasPriceCapServiceConfig = L1DynamicGasPriceCapServiceConfig(
@@ -318,18 +318,18 @@ class CoordinatorConfigTest {
gasPriceCapsCheckCoefficient = 0.9,
historicBaseFeePerBlobGasLowerBound = 100_000_000u,
historicAvgRewardConstant = 100_000_000u,
timeOfDayMultipliers = expectedTimeOfDayMultipliers
timeOfDayMultipliers = expectedTimeOfDayMultipliers,
),
feeHistoryFetcher = L1DynamicGasPriceCapServiceConfig.FeeHistoryFetcher(
fetchInterval = Duration.parse("PT1S"),
maxBlockCount = 1000U,
rewardPercentiles = listOf(10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0),
numOfBlocksBeforeLatest = 4U,
endpoint = null
endpoint = null,
),
feeHistoryStorage = L1DynamicGasPriceCapServiceConfig.FeeHistoryStorage(
storagePeriod = Duration.parse("PT2M")
)
storagePeriod = Duration.parse("PT2M"),
),
)
private val coordinatorConfig = CoordinatorConfig(
@@ -351,11 +351,11 @@ class CoordinatorConfigTest {
l2Signer = l2SignerConfig,
messageAnchoring = MessageAnchoringConfigTomlDto().reified(
l1DefaultEndpoint = l1Config.rpcEndpoint,
l2DefaultEndpoint = l2Config.rpcEndpoint
l2DefaultEndpoint = l2Config.rpcEndpoint,
),
l2NetworkGasPricingService = l2NetworkGasPricingServiceConfig,
l1DynamicGasPriceCapService = l1DynamicGasPriceCapServiceConfig,
proversConfig = proversConfig
proversConfig = proversConfig,
)
}
@@ -371,18 +371,18 @@ class CoordinatorConfigTest {
Path.of("../../config/coordinator/coordinator-docker-traces-v2-override.config.toml"),
Path.of("../../config/coordinator/coordinator-docker-web3signer-override.config.toml"),
Path.of("../../config/coordinator/coordinator-local-dev.config.overrides.toml"),
Path.of("../../config/coordinator/coordinator-local-dev.config-traces-v2.overrides.toml")
Path.of("../../config/coordinator/coordinator-local-dev.config-traces-v2.overrides.toml"),
),
tracesLimitsFileV2 = Path.of("../../config/common/traces-limits-v2.toml"),
gasPriceCapTimeOfDayMultipliersFile = Path.of("../../config/common/gas-price-cap-time-of-day-multipliers.toml"),
smartContractErrorsFile = Path.of("../../config/common/smart-contract-errors.toml")
smartContractErrorsFile = Path.of("../../config/common/smart-contract-errors.toml"),
)
}
private fun pathToResource(resource: String): Path {
return Paths.get(
this::class.java.classLoader.getResource(resource)?.toURI()
?: error("Resource not found: $resource")
?: error("Resource not found: $resource"),
)
}
@@ -392,7 +392,7 @@ class CoordinatorConfigTest {
coordinatorConfigFiles = listOf(pathToResource("configs/coordinator.config.toml")),
tracesLimitsFileV2 = pathToResource("configs/traces-limits-v2.toml"),
gasPriceCapTimeOfDayMultipliersFile = pathToResource("configs/gas-price-cap-time-of-day-multipliers.toml"),
smartContractErrorsFile = pathToResource("configs/smart-contract-errors.toml")
smartContractErrorsFile = pathToResource("configs/smart-contract-errors.toml"),
)
assertEquals(coordinatorConfig, configs)
@@ -404,18 +404,18 @@ class CoordinatorConfigTest {
val config = loadConfigs(
coordinatorConfigFiles = listOf(
pathToResource("configs/coordinator.config.toml"),
pathToResource("configs/coordinator-web3signer-override.config.toml")
pathToResource("configs/coordinator-web3signer-override.config.toml"),
),
tracesLimitsFileV2 = pathToResource("configs/traces-limits-v2.toml"),
gasPriceCapTimeOfDayMultipliersFile = pathToResource("configs/gas-price-cap-time-of-day-multipliers.toml"),
smartContractErrorsFile = pathToResource("configs/smart-contract-errors.toml")
smartContractErrorsFile = pathToResource("configs/smart-contract-errors.toml"),
)
val expectedConfig =
coordinatorConfig.copy(
finalizationSigner = finalizationSigner.copy(type = SignerConfig.Type.Web3Signer),
dataSubmissionSigner = dataSubmissionSigner.copy(type = SignerConfig.Type.Web3Signer),
l2Signer = l2SignerConfig.copy(type = SignerConfig.Type.Web3Signer)
l2Signer = l2SignerConfig.copy(type = SignerConfig.Type.Web3Signer),
)
assertThat(config).isEqualTo(expectedConfig)
@@ -426,11 +426,11 @@ class CoordinatorConfigTest {
val config = loadConfigs(
coordinatorConfigFiles = listOf(
pathToResource("configs/coordinator.config.toml"),
pathToResource("configs/coordinator-traces-v2-override.config.toml")
pathToResource("configs/coordinator-traces-v2-override.config.toml"),
),
tracesLimitsFileV2 = pathToResource("configs/traces-limits-v2.toml"),
gasPriceCapTimeOfDayMultipliersFile = pathToResource("configs/gas-price-cap-time-of-day-multipliers.toml"),
smartContractErrorsFile = pathToResource("configs/smart-contract-errors.toml")
smartContractErrorsFile = pathToResource("configs/smart-contract-errors.toml"),
)
val expectedConfig =
@@ -441,31 +441,31 @@ class CoordinatorConfigTest {
transactionCostCalculatorConfig =
l2NetworkGasPricingServiceConfig.legacy.transactionCostCalculatorConfig?.copy(
compressedTxSize = 350,
expectedGas = 29400
)
)
expectedGas = 29400,
),
),
),
traces = tracesConfig.copy(
blobCompressorVersion = BlobCompressorVersion.V1_2,
expectedTracesApiVersionV2 = "v0.8.0-rc8",
conflationV2 = tracesConfig.conflationV2,
countersV2 = tracesConfig.countersV2
countersV2 = tracesConfig.countersV2,
),
proversConfig = proversConfig.copy(
proverA = proversConfig.proverA.copy(
execution = proversConfig.proverA.execution.copy(
requestsDirectory = Path.of("/data/prover/v3/execution/requests"),
responsesDirectory = Path.of("/data/prover/v3/execution/responses")
responsesDirectory = Path.of("/data/prover/v3/execution/responses"),
),
blobCompression = proversConfig.proverA.blobCompression.copy(
requestsDirectory = Path.of("/data/prover/v3/compression/requests"),
responsesDirectory = Path.of("/data/prover/v3/compression/responses")
responsesDirectory = Path.of("/data/prover/v3/compression/responses"),
),
proofAggregation = proversConfig.proverA.proofAggregation.copy(
requestsDirectory = Path.of("/data/prover/v3/aggregation/requests"),
responsesDirectory = Path.of("/data/prover/v3/aggregation/responses")
)
)
responsesDirectory = Path.of("/data/prover/v3/aggregation/responses"),
),
),
),
messageAnchoring = MessageAnchoringConfigTomlDto().copy(
l1Endpoint = URI("http://l1-endpoint-for-anchoring:8545").toURL(),
@@ -475,12 +475,12 @@ class CoordinatorConfigTest {
anchoringTickInterval = 1.seconds.toJavaDuration(),
l1RequestRetries = RequestRetryConfigTomlFriendly(
maxRetries = 10,
failuresWarningThreshold = 1
)
failuresWarningThreshold = 1,
),
).reified(
l1DefaultEndpoint = l1Config.rpcEndpoint,
l2DefaultEndpoint = l2Config.rpcEndpoint
)
l2DefaultEndpoint = l2Config.rpcEndpoint,
),
)
assertThat(config).isEqualTo(expectedConfig)
@@ -489,7 +489,7 @@ class CoordinatorConfigTest {
@Test
fun invalidConfigReturnsErrorResult() {
val configsResult = loadConfigsOrError<TestConfig>(
configFiles = listOf(pathToResource("configs/coordinator.config.toml"))
configFiles = listOf(pathToResource("configs/coordinator.config.toml")),
)
assertThat(configsResult.getError()).contains("'extraField': Missing String from config")
@@ -498,17 +498,17 @@ class CoordinatorConfigTest {
@Test
fun testInvalidAggregationByTargetBlockNumberWhenL2InclusiveBlockNumberToStopAndFlushAggregationSpecified() {
val aggregationConfigWithoutTargetBlockNumber = aggregationConfig.copy(
_targetEndBlocks = emptyList()
_targetEndBlocks = emptyList(),
)
val conflationConfigWithTargetBlockNumber = conflationConfig.copy(
_conflationTargetEndBlockNumbers = listOf(100L)
_conflationTargetEndBlockNumbers = listOf(100L),
)
val exception = assertThrows<IllegalArgumentException> {
coordinatorConfig.copy(
l2InclusiveBlockNumberToStopAndFlushAggregation = 100uL,
proofAggregation = aggregationConfigWithoutTargetBlockNumber,
conflation = conflationConfigWithTargetBlockNumber
conflation = conflationConfigWithTargetBlockNumber,
)
}
assertThat(exception.message)
@@ -518,40 +518,40 @@ class CoordinatorConfigTest {
@Test
fun testInvalidConflationByTargetBlockNumberWhenL2InclusiveBlockNumberToStopAndFlushAggregationSpecified() {
val aggregationConfigWithTargetBlockNumber = aggregationConfig.copy(
_targetEndBlocks = listOf(100L)
_targetEndBlocks = listOf(100L),
)
val conflationConfigWithoutTargetBlockNumber = conflationConfig.copy(
_conflationTargetEndBlockNumbers = emptyList()
_conflationTargetEndBlockNumbers = emptyList(),
)
val exception = assertThrows<IllegalArgumentException> {
coordinatorConfig.copy(
l2InclusiveBlockNumberToStopAndFlushAggregation = 100uL,
proofAggregation = aggregationConfigWithTargetBlockNumber,
conflation = conflationConfigWithoutTargetBlockNumber
conflation = conflationConfigWithoutTargetBlockNumber,
)
}
assertThat(exception.message)
.isEqualTo(
"conflation.conflationTargetEndBlockNumbers should contain the " +
"l2InclusiveBlockNumberToStopAndFlushAggregation"
"l2InclusiveBlockNumberToStopAndFlushAggregation",
)
}
@Test
fun testValidAggrAndConflationByTargetBlockNumberWhenL2InclusiveBlockNumberToStopAndFlushAggregationSpecified() {
val aggregationConfigWithoutSwithBlockNumber = aggregationConfig.copy(
_targetEndBlocks = listOf(10L, 100L)
_targetEndBlocks = listOf(10L, 100L),
)
val conflationConfigWithTargetBlockNumber = conflationConfig.copy(
_conflationTargetEndBlockNumbers = listOf(100L)
_conflationTargetEndBlockNumbers = listOf(100L),
)
assertDoesNotThrow {
coordinatorConfig.copy(
l2InclusiveBlockNumberToStopAndFlushAggregation = 100uL,
proofAggregation = aggregationConfigWithoutSwithBlockNumber,
conflation = conflationConfigWithTargetBlockNumber
conflation = conflationConfigWithTargetBlockNumber,
)
}
}

View File

@@ -168,5 +168,5 @@ val expectedTimeOfDayMultipliers = mapOf(
"SATURDAY_20" to 1.5073787902995706,
"SATURDAY_21" to 1.5605139580010123,
"SATURDAY_22" to 1.5885303316932382,
"SATURDAY_23" to 1.6169891066719597
"SATURDAY_23" to 1.6169891066719597,
)

View File

@@ -55,6 +55,6 @@ val expectedTracesLimitsV2 = TracesCountersV2(
TracingModuleV2.BLOCK_KECCAK to 46u,
TracingModuleV2.BLOCK_L1_SIZE to 47u,
TracingModuleV2.BLOCK_L2_L1_LOGS to 48u,
TracingModuleV2.BLOCK_TRANSACTIONS to 49u
)
TracingModuleV2.BLOCK_TRANSACTIONS to 49u,
),
)

View File

@@ -21,7 +21,7 @@ import kotlin.time.toJavaDuration
class L2NetworkGasPricingConfigTest {
data class Config(
val l2NetworkGasPricing: L2NetworkGasPricingTomlDto
val l2NetworkGasPricing: L2NetworkGasPricingTomlDto,
)
private fun parseConfig(toml: String): L2NetworkGasPricingTomlDto {
@@ -135,7 +135,7 @@ class L2NetworkGasPricingConfigTest {
maxRetries = 3,
timeout = 6.seconds.toJavaDuration(),
backoffDelay = 1.seconds.toJavaDuration(),
failuresWarningThreshold = 2
failuresWarningThreshold = 2,
),
priceUpdateInterval = Duration.parse("PT12S"),
@@ -152,29 +152,29 @@ class L2NetworkGasPricingConfigTest {
naiveGasPricing = NaiveGasPricingTomlDto(
baseFeeCoefficient = 0.1,
priorityFeeCoefficient = 1.0,
baseFeeBlobCoefficient = 0.1
)
baseFeeBlobCoefficient = 0.1,
),
),
variableCostPricing = VariableCostPricingTomlDto(
gasPriceFixedCost = 3000000u,
legacyFeesMultiplier = 1.2,
margin = 4.0,
variableCostUpperBound = 10_000_000_001u,
variableCostLowerBound = 90_000_001u
variableCostLowerBound = 90_000_001u,
),
jsonRpcPricingPropagation = JsonRpcPricingPropagationTomlDto(
gethGasPriceUpdateRecipients = listOf(
URI("http://traces-node:8545/").toURL(),
URI("http://l2-node:8545/").toURL()
URI("http://l2-node:8545/").toURL(),
),
besuGasPriceUpdateRecipients = listOf(
URI("http://sequencer:8545/").toURL()
)
URI("http://sequencer:8545/").toURL(),
),
),
extraDataPricingPropagation = ExtraDataPricingPropagationTomlDto(
extraDataUpdateRecipient = URI("http://sequencer:8545/").toURL()
)
)
extraDataUpdateRecipient = URI("http://sequencer:8545/").toURL(),
),
),
)
}
@@ -187,7 +187,7 @@ class L2NetworkGasPricingConfigTest {
maxRetries = 3,
timeout = 6.seconds.toJavaDuration(),
backoffDelay = 1.seconds.toJavaDuration(),
failuresWarningThreshold = 2
failuresWarningThreshold = 2,
),
priceUpdateInterval = Duration.parse("PT12S"),
@@ -201,28 +201,28 @@ class L2NetworkGasPricingConfigTest {
type = LegacyGasPricingTomlDto.Type.SampleTransaction,
gasPriceUpperBound = 10_000_000_000u,
gasPriceLowerBound = 90_000_000u,
naiveGasPricing = null
naiveGasPricing = null,
),
variableCostPricing = VariableCostPricingTomlDto(
gasPriceFixedCost = 3000000u,
legacyFeesMultiplier = 1.2,
margin = 4.0,
variableCostUpperBound = 10_000_000_001u,
variableCostLowerBound = 90_000_001u
variableCostLowerBound = 90_000_001u,
),
jsonRpcPricingPropagation = JsonRpcPricingPropagationTomlDto(
gethGasPriceUpdateRecipients = listOf(
URI("http://traces-node:8545/").toURL(),
URI("http://l2-node:8545/").toURL()
URI("http://l2-node:8545/").toURL(),
),
besuGasPriceUpdateRecipients = listOf(
URI("http://sequencer:8545/").toURL()
)
URI("http://sequencer:8545/").toURL(),
),
),
extraDataPricingPropagation = ExtraDataPricingPropagationTomlDto(
extraDataUpdateRecipient = URI("http://sequencer:8545/").toURL()
)
)
extraDataUpdateRecipient = URI("http://sequencer:8545/").toURL(),
),
),
)
}
@@ -233,14 +233,14 @@ class L2NetworkGasPricingConfigTest {
maxRetries = 3u,
timeout = 6.seconds,
backoffDelay = 1.seconds,
failuresWarningThreshold = 2u
failuresWarningThreshold = 2u,
)
assertThat(config).isEqualTo(
L2NetworkGasPricingService.Config(
feeHistoryFetcherConfig = FeeHistoryFetcherImpl.Config(
feeHistoryBlockCount = 50U,
feeHistoryRewardPercentile = 15.0
feeHistoryRewardPercentile = 15.0,
),
legacy = L2NetworkGasPricingService.LegacyGasPricingCalculatorConfig(
naiveGasPricingCalculatorConfig = GasUsageRatioWeightedAverageFeesCalculator.Config(
@@ -248,24 +248,24 @@ class L2NetworkGasPricingConfigTest {
priorityFeeCoefficient = 1.0,
baseFeeBlobCoefficient = 0.1,
blobSubmissionExpectedExecutionGas = 213_000,
expectedBlobGas = 131072
expectedBlobGas = 131072,
),
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
10_000_000_000.0,
90_000_000.0,
0.0
0.0,
),
transactionCostCalculatorConfig = null
transactionCostCalculatorConfig = null,
),
jsonRpcGasPriceUpdaterConfig = GasPriceUpdaterImpl.Config(
gethEndpoints = listOf(
URI("http://traces-node:8545/").toURL(),
URI("http://l2-node:8545/").toURL()
URI("http://l2-node:8545/").toURL(),
),
besuEndPoints = listOf(
URI("http://sequencer:8545/").toURL()
URI("http://sequencer:8545/").toURL(),
),
retryConfig = l2NetworkGasPricingRequestretryConfig
retryConfig = l2NetworkGasPricingRequestretryConfig,
),
jsonRpcPriceUpdateInterval = 12.seconds,
extraDataPricingPropagationEnabled = true,
@@ -274,22 +274,22 @@ class L2NetworkGasPricingConfigTest {
blobSubmissionExpectedExecutionGas = 213_000u,
bytesPerDataSubmission = 131072u,
expectedBlobGas = 131072u,
margin = 4.0
margin = 4.0,
),
variableFeesCalculatorBounds = BoundableFeeCalculator.Config(
feeUpperBound = 10_000_000_001.0,
feeLowerBound = 90_000_001.0,
feeMargin = 0.0
feeMargin = 0.0,
),
extraDataCalculatorConfig = MinerExtraDataV1CalculatorImpl.Config(
fixedCostInKWei = 3000u,
ethGasPriceMultiplier = 1.2
ethGasPriceMultiplier = 1.2,
),
extraDataUpdaterConfig = ExtraDataV1UpdaterImpl.Config(
sequencerEndpoint = URI(/* str = */ "http://sequencer:8545/").toURL(),
retryConfig = l2NetworkGasPricingRequestretryConfig
)
)
sequencerEndpoint = URI("http://sequencer:8545/").toURL(),
retryConfig = l2NetworkGasPricingRequestretryConfig,
),
),
)
}
@@ -300,38 +300,38 @@ class L2NetworkGasPricingConfigTest {
maxRetries = 3u,
timeout = 6.seconds,
backoffDelay = 1.seconds,
failuresWarningThreshold = 2u
failuresWarningThreshold = 2u,
)
assertThat(config).isEqualTo(
L2NetworkGasPricingService.Config(
feeHistoryFetcherConfig = FeeHistoryFetcherImpl.Config(
feeHistoryBlockCount = 50U,
feeHistoryRewardPercentile = 15.0
feeHistoryRewardPercentile = 15.0,
),
legacy = L2NetworkGasPricingService.LegacyGasPricingCalculatorConfig(
naiveGasPricingCalculatorConfig = null,
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
10_000_000_000.0,
90_000_000.0,
0.0
0.0,
),
transactionCostCalculatorConfig = TransactionCostCalculator.Config(
sampleTransactionCostMultiplier = 1.0,
fixedCostWei = 3000000u,
compressedTxSize = 125,
expectedGas = 21000
)
expectedGas = 21000,
),
),
jsonRpcGasPriceUpdaterConfig = GasPriceUpdaterImpl.Config(
gethEndpoints = listOf(
URI("http://traces-node:8545/").toURL(),
URI("http://l2-node:8545/").toURL()
URI("http://l2-node:8545/").toURL(),
),
besuEndPoints = listOf(
URI("http://sequencer:8545/").toURL()
URI("http://sequencer:8545/").toURL(),
),
retryConfig = l2NetworkGasPricingRequestretryConfig
retryConfig = l2NetworkGasPricingRequestretryConfig,
),
jsonRpcPriceUpdateInterval = 12.seconds,
extraDataPricingPropagationEnabled = true,
@@ -340,22 +340,22 @@ class L2NetworkGasPricingConfigTest {
blobSubmissionExpectedExecutionGas = 213_000u,
bytesPerDataSubmission = 131072u,
expectedBlobGas = 131072u,
margin = 4.0
margin = 4.0,
),
variableFeesCalculatorBounds = BoundableFeeCalculator.Config(
feeUpperBound = 10_000_000_001.0,
feeLowerBound = 90_000_001.0,
feeMargin = 0.0
feeMargin = 0.0,
),
extraDataCalculatorConfig = MinerExtraDataV1CalculatorImpl.Config(
fixedCostInKWei = 3000u,
ethGasPriceMultiplier = 1.2
ethGasPriceMultiplier = 1.2,
),
extraDataUpdaterConfig = ExtraDataV1UpdaterImpl.Config(
sequencerEndpoint = URI(/* str = */ "http://sequencer:8545/").toURL(),
retryConfig = l2NetworkGasPricingRequestretryConfig
)
)
sequencerEndpoint = URI("http://sequencer:8545/").toURL(),
retryConfig = l2NetworkGasPricingRequestretryConfig,
),
),
)
}
@@ -400,28 +400,28 @@ class L2NetworkGasPricingConfigTest {
maxRetries = 3u,
timeout = 6.seconds,
backoffDelay = 1.seconds,
failuresWarningThreshold = 2u
failuresWarningThreshold = 2u,
)
assertThat(config).isEqualTo(
L2NetworkGasPricingService.Config(
feeHistoryFetcherConfig = FeeHistoryFetcherImpl.Config(
feeHistoryBlockCount = 50U,
feeHistoryRewardPercentile = 15.0
feeHistoryRewardPercentile = 15.0,
),
legacy = L2NetworkGasPricingService.LegacyGasPricingCalculatorConfig(
naiveGasPricingCalculatorConfig = null,
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
10_000_000_000.0,
90_000_000.0,
0.0
0.0,
),
transactionCostCalculatorConfig = TransactionCostCalculator.Config(
sampleTransactionCostMultiplier = 1.0,
fixedCostWei = 3000000u,
compressedTxSize = 125,
expectedGas = 21000
)
expectedGas = 21000,
),
),
jsonRpcGasPriceUpdaterConfig = null,
jsonRpcPriceUpdateInterval = 12.seconds,
@@ -431,22 +431,22 @@ class L2NetworkGasPricingConfigTest {
blobSubmissionExpectedExecutionGas = 213_000u,
bytesPerDataSubmission = 131072u,
expectedBlobGas = 131072u,
margin = 4.0
margin = 4.0,
),
variableFeesCalculatorBounds = BoundableFeeCalculator.Config(
feeUpperBound = 10_000_000_001.0,
feeLowerBound = 90_000_001.0,
feeMargin = 0.0
feeMargin = 0.0,
),
extraDataCalculatorConfig = MinerExtraDataV1CalculatorImpl.Config(
fixedCostInKWei = 3000u,
ethGasPriceMultiplier = 1.2
ethGasPriceMultiplier = 1.2,
),
extraDataUpdaterConfig = ExtraDataV1UpdaterImpl.Config(
sequencerEndpoint = URI(/* str = */ "http://sequencer:8545/").toURL(),
retryConfig = l2NetworkGasPricingRequestretryConfig
)
)
sequencerEndpoint = URI("http://sequencer:8545/").toURL(),
retryConfig = l2NetworkGasPricingRequestretryConfig,
),
),
)
}
@@ -496,28 +496,28 @@ class L2NetworkGasPricingConfigTest {
maxRetries = 3u,
timeout = 6.seconds,
backoffDelay = 1.seconds,
failuresWarningThreshold = 2u
failuresWarningThreshold = 2u,
)
assertThat(config).isEqualTo(
L2NetworkGasPricingService.Config(
feeHistoryFetcherConfig = FeeHistoryFetcherImpl.Config(
feeHistoryBlockCount = 50U,
feeHistoryRewardPercentile = 15.0
feeHistoryRewardPercentile = 15.0,
),
legacy = L2NetworkGasPricingService.LegacyGasPricingCalculatorConfig(
naiveGasPricingCalculatorConfig = null,
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
10_000_000_000.0,
90_000_000.0,
0.0
0.0,
),
transactionCostCalculatorConfig = TransactionCostCalculator.Config(
sampleTransactionCostMultiplier = 1.0,
fixedCostWei = 3000000u,
compressedTxSize = 125,
expectedGas = 21000
)
expectedGas = 21000,
),
),
jsonRpcGasPriceUpdaterConfig = null,
jsonRpcPriceUpdateInterval = 12.seconds,
@@ -527,22 +527,22 @@ class L2NetworkGasPricingConfigTest {
blobSubmissionExpectedExecutionGas = 213_000u,
bytesPerDataSubmission = 131072u,
expectedBlobGas = 131072u,
margin = 4.0
margin = 4.0,
),
variableFeesCalculatorBounds = BoundableFeeCalculator.Config(
feeUpperBound = 10_000_000_001.0,
feeLowerBound = 90_000_001.0,
feeMargin = 0.0
feeMargin = 0.0,
),
extraDataCalculatorConfig = MinerExtraDataV1CalculatorImpl.Config(
fixedCostInKWei = 3000u,
ethGasPriceMultiplier = 1.2
ethGasPriceMultiplier = 1.2,
),
extraDataUpdaterConfig = ExtraDataV1UpdaterImpl.Config(
sequencerEndpoint = URI(/* str = */ "http://sequencer:8545/").toURL(),
retryConfig = l2NetworkGasPricingRequestretryConfig
)
)
sequencerEndpoint = URI("http://sequencer:8545/").toURL(),
retryConfig = l2NetworkGasPricingRequestretryConfig,
),
),
)
}
}

View File

@@ -14,7 +14,7 @@ class MessageAnchoringConfigTest {
private val l1DefaultEndpoint = URI("http://l1-default-rpc-endpoint:8545").toURL()
private val l2DefaultEndpoint = URI("http://l2-default-rpc-endpoint:8545").toURL()
data class Config(
val messageAnchoring: MessageAnchoringConfigTomlDto = MessageAnchoringConfigTomlDto()
val messageAnchoring: MessageAnchoringConfigTomlDto = MessageAnchoringConfigTomlDto(),
)
private fun parseConfig(toml: String): MessageAnchoringConfig {
@@ -27,7 +27,7 @@ class MessageAnchoringConfigTest {
.let {
it.messageAnchoring.reified(
l1DefaultEndpoint = l1DefaultEndpoint,
l2DefaultEndpoint = l2DefaultEndpoint
l2DefaultEndpoint = l2DefaultEndpoint,
)
}
}
@@ -74,13 +74,13 @@ class MessageAnchoringConfigTest {
maxRetries = 10u,
timeout = 100.seconds,
backoffDelay = 11.seconds,
failuresWarningThreshold = 1u
failuresWarningThreshold = 1u,
),
l2RequestRetryConfig = RetryConfig(
maxRetries = 20u,
timeout = 200.seconds,
backoffDelay = 21.seconds,
failuresWarningThreshold = 2u
failuresWarningThreshold = 2u,
),
l1EventPollingInterval = 30.seconds,
l1EventPollingTimeout = 6.seconds,
@@ -88,8 +88,8 @@ class MessageAnchoringConfigTest {
l1EventSearchBlockChunk = 123u,
anchoringTickInterval = 3.seconds,
messageQueueCapacity = 321u,
maxMessagesToAnchorPerL2Transaction = 54u
)
maxMessagesToAnchorPerL2Transaction = 54u,
),
)
}
@@ -111,13 +111,13 @@ class MessageAnchoringConfigTest {
maxRetries = null,
timeout = null,
backoffDelay = 1.seconds,
failuresWarningThreshold = 3u
failuresWarningThreshold = 3u,
),
l2RequestRetryConfig = RetryConfig(
maxRetries = null,
timeout = null,
backoffDelay = 1.seconds,
failuresWarningThreshold = 3u
failuresWarningThreshold = 3u,
),
l1EventPollingInterval = 12.seconds,
l1EventPollingTimeout = 6.seconds,
@@ -125,8 +125,8 @@ class MessageAnchoringConfigTest {
l1EventSearchBlockChunk = 1000u,
anchoringTickInterval = 2.seconds,
messageQueueCapacity = 10_000u,
maxMessagesToAnchorPerL2Transaction = 100u
)
maxMessagesToAnchorPerL2Transaction = 100u,
),
)
}
}

View File

@@ -13,7 +13,7 @@ import kotlin.time.Duration.Companion.seconds
class ProverConfigTest {
data class Config(
val prover: ProverConfigTomlDto
val prover: ProverConfigTomlDto,
)
private fun parseConfig(toml: String): ProversConfig {
@@ -62,8 +62,8 @@ class ProverConfigTest {
inprogressRequestWritingSuffix = ".OVERRIDE_inprogress_coordinator_writing",
inprogressProvingSuffixPattern = "OVERRIDE_\\.inprogress\\.prover.*",
pollingInterval = 10.seconds,
pollingTimeout = 10.minutes
)
pollingTimeout = 10.minutes,
),
)
assertThat(config.blobCompression).isEqualTo(
FileBasedProverConfig(
@@ -72,8 +72,8 @@ class ProverConfigTest {
inprogressRequestWritingSuffix = ".inprogress_coordinator_writing",
inprogressProvingSuffixPattern = "\\.inprogress\\.prover.*",
pollingInterval = 20.seconds,
pollingTimeout = 20.minutes
)
pollingTimeout = 20.minutes,
),
)
assertThat(config.proofAggregation).isEqualTo(
FileBasedProverConfig(
@@ -82,8 +82,8 @@ class ProverConfigTest {
inprogressRequestWritingSuffix = ".inprogress_coordinator_writing",
inprogressProvingSuffixPattern = "\\.inprogress\\.prover.*",
pollingInterval = 10.seconds,
pollingTimeout = 10.minutes
)
pollingTimeout = 10.minutes,
),
)
}
@@ -122,8 +122,8 @@ class ProverConfigTest {
inprogressRequestWritingSuffix = ".NEW_OVERRIDE_2_inprogress_coordinator_writing",
inprogressProvingSuffixPattern = "NEW_OVERRIDE_2\\.inprogress\\.prover.*",
pollingInterval = 10.seconds,
pollingTimeout = 5.minutes
)
pollingTimeout = 5.minutes,
),
)
assertThat(config.proverB!!.blobCompression).isEqualTo(
FileBasedProverConfig(
@@ -132,8 +132,8 @@ class ProverConfigTest {
inprogressRequestWritingSuffix = ".NEW_OVERRIDE_inprogress_coordinator_writing",
inprogressProvingSuffixPattern = "\\.inprogress\\.prover.*",
pollingInterval = 12.seconds,
pollingTimeout = 12.minutes
)
pollingTimeout = 12.minutes,
),
)
assertThat(config.proverB!!.proofAggregation).isEqualTo(
FileBasedProverConfig(
@@ -142,8 +142,8 @@ class ProverConfigTest {
inprogressRequestWritingSuffix = ".NEW_OVERRIDE_inprogress_coordinator_writing",
inprogressProvingSuffixPattern = "\\.inprogress\\.prover.*",
pollingInterval = 10.seconds,
pollingTimeout = 5.minutes
)
pollingTimeout = 5.minutes,
),
)
}
}

View File

@@ -44,7 +44,7 @@ class BlockCreationMonitorTest {
pollingInterval = 100.milliseconds,
blocksToFinalization = 2L,
blocksFetchLimit = 500,
lastL2BlockNumberToProcessInclusive = null
lastL2BlockNumberToProcessInclusive = null,
)
private lateinit var vertx: Vertx
private lateinit var lastProvenBlockNumberProvider: LastProvenBlockNumberProviderDouble
@@ -62,7 +62,7 @@ class BlockCreationMonitorTest {
}
private class LastProvenBlockNumberProviderDouble(
initialValue: ULong
initialValue: ULong,
) : LastProvenBlockNumberProviderAsync {
var lastProvenBlock: AtomicLong = AtomicLong(initialValue.toLong())
override fun getLastProvenBlockNumber(): SafeFuture<Long> {
@@ -73,7 +73,7 @@ class BlockCreationMonitorTest {
fun createBlockCreationMonitor(
startingBlockNumberExclusive: Long = 99,
blockCreationListener: BlockCreationListener = this.blockCreationListener,
config: BlockCreationMonitor.Config = this.config
config: BlockCreationMonitor.Config = this.config,
): BlockCreationMonitor {
return BlockCreationMonitor(
this.vertx,
@@ -81,7 +81,7 @@ class BlockCreationMonitorTest {
startingBlockNumberExclusive = startingBlockNumberExclusive,
blockCreationListener,
lastProvenBlockNumberProvider,
config
config,
)
}
@@ -94,14 +94,14 @@ class BlockCreationMonitorTest {
fakeL2RpcNode = TestingJsonRpcServer(
vertx = vertx,
recordRequestsResponses = true,
responseObjectMapper = ethApiObjectMapper
responseObjectMapper = ethApiObjectMapper,
)
blockCreationListener = BlockCreationListenerDouble()
web3jClient = ExtendedWeb3JImpl(
createWeb3jHttpClient(
rpcUrl = "http://localhost:${fakeL2RpcNode.boundPort}",
log = LogManager.getLogger("test.client.l2.web3j")
)
log = LogManager.getLogger("test.client.l2.web3j"),
),
)
lastProvenBlockNumberProvider = LastProvenBlockNumberProviderDouble(99u)
}
@@ -116,7 +116,7 @@ class BlockCreationMonitorTest {
startBlockNumber: ULong,
numberOfBlocks: Int,
startBlockHash: ByteArray = ByteArrayExt.random32(),
startBlockParentHash: ByteArray = ByteArrayExt.random32()
startBlockParentHash: ByteArray = ByteArrayExt.random32(),
): List<Block> {
var blockHash = startBlockHash
var parentHash = startBlockParentHash
@@ -124,7 +124,7 @@ class BlockCreationMonitorTest {
createBlock(
number = startBlockNumber + i.toULong(),
hash = blockHash,
parentHash = parentHash
parentHash = parentHash,
).also {
blockHash = ByteArrayExt.random32()
parentHash = it.hash
@@ -147,7 +147,7 @@ class BlockCreationMonitorTest {
fun `should stop fetching blocks after lastBlockNumberInclusiveToProcess`() {
monitor = createBlockCreationMonitor(
startingBlockNumberExclusive = 99,
config = config.copy(lastL2BlockNumberToProcessInclusive = 103u)
config = config.copy(lastL2BlockNumberToProcessInclusive = 103u),
)
setupFakeExecutionLayerWithBlocks(createBlocks(startBlockNumber = 99u, numberOfBlocks = 20))
@@ -170,7 +170,7 @@ class BlockCreationMonitorTest {
fun `should notify lister only after block is considered final on L2`() {
monitor = createBlockCreationMonitor(
startingBlockNumberExclusive = 99,
config = config.copy(blocksToFinalization = 2, blocksFetchLimit = 500)
config = config.copy(blocksToFinalization = 2, blocksFetchLimit = 500),
)
setupFakeExecutionLayerWithBlocks(createBlocks(startBlockNumber = 99u, numberOfBlocks = 200))
@@ -217,7 +217,7 @@ class BlockCreationMonitorTest {
monitor = createBlockCreationMonitor(
startingBlockNumberExclusive = 99,
blockCreationListener = fakeBuggyLister,
config = config.copy(blocksToFinalization = 2, lastL2BlockNumberToProcessInclusive = 112u)
config = config.copy(blocksToFinalization = 2, lastL2BlockNumberToProcessInclusive = 112u),
)
setupFakeExecutionLayerWithBlocks(createBlocks(startBlockNumber = 99u, numberOfBlocks = 20))
@@ -232,14 +232,14 @@ class BlockCreationMonitorTest {
// assert it got block only once and in order
assertThat(blockCreationListener.blocksReceived.map { it.number }).containsExactly(
100UL, 101UL, 102UL, 103UL, 104UL, 105UL, 106UL, 107UL, 108UL, 109UL, 110UL
100UL, 101UL, 102UL, 103UL, 104UL, 105UL, 106UL, 107UL, 108UL, 109UL, 110UL,
)
}
@Test
fun `should be resilient to connection failures`() {
monitor = createBlockCreationMonitor(
startingBlockNumberExclusive = 99
startingBlockNumberExclusive = 99,
)
setupFakeExecutionLayerWithBlocks(createBlocks(startBlockNumber = 99u, numberOfBlocks = 200))
@@ -268,7 +268,7 @@ class BlockCreationMonitorTest {
@Test
fun `should stop when reorg is detected above blocksToFinalization limit - manual intervention necessary`() {
monitor = createBlockCreationMonitor(
startingBlockNumberExclusive = 99
startingBlockNumberExclusive = 99,
)
// simulate reorg by changing parent hash of block 105
@@ -300,7 +300,7 @@ class BlockCreationMonitorTest {
fun `should poll in order when response takes longer that polling interval`() {
monitor = createBlockCreationMonitor(
startingBlockNumberExclusive = 99,
config = config.copy(pollingInterval = 100.milliseconds)
config = config.copy(pollingInterval = 100.milliseconds),
)
val blocks = createBlocks(startBlockNumber = 99u, numberOfBlocks = 20)
@@ -318,7 +318,7 @@ class BlockCreationMonitorTest {
102UL,
103UL,
104UL,
105UL
105UL,
)
}
}
@@ -326,7 +326,7 @@ class BlockCreationMonitorTest {
@Test
fun `start allow 2nd call when already started`() {
monitor = createBlockCreationMonitor(
startingBlockNumberExclusive = 99
startingBlockNumberExclusive = 99,
)
setupFakeExecutionLayerWithBlocks(createBlocks(startBlockNumber = 99u, numberOfBlocks = 5))
monitor.start().get()
@@ -337,7 +337,7 @@ class BlockCreationMonitorTest {
fun `should stop fetching blocks when gap is greater than fetch limit and resume upon catchup`() {
monitor = createBlockCreationMonitor(
startingBlockNumberExclusive = 99,
config = config.copy(blocksToFinalization = 0, blocksFetchLimit = 5)
config = config.copy(blocksToFinalization = 0, blocksFetchLimit = 5),
)
setupFakeExecutionLayerWithBlocks(createBlocks(startBlockNumber = 99u, numberOfBlocks = 30))

View File

@@ -27,23 +27,23 @@ class ConsecutiveProvenBlobsProviderWithLastEndBlockNumberTrackerTest {
endBlockNumber = 2UL,
startBlockTimestamp = Instant.DISTANT_PAST,
endBlockTimestamp = Instant.DISTANT_PAST,
expectedShnarf = Random.nextBytes(32)
expectedShnarf = Random.nextBytes(32),
)
val baseBlobAndBatchCounters = BlobAndBatchCounters(
blobCounters = baseBlobCounters,
executionProofs = BlockIntervals(1UL, listOf(2UL, 3UL))
executionProofs = BlockIntervals(1UL, listOf(2UL, 3UL)),
)
val expectedEndBLockNumber = 10UL
val lastBlobAndBatchCounters = baseBlobAndBatchCounters.copy(
blobCounters = baseBlobCounters.copy(startBlockNumber = 3UL, endBlockNumber = expectedEndBLockNumber)
blobCounters = baseBlobCounters.copy(startBlockNumber = 3UL, endBlockNumber = expectedEndBLockNumber),
)
whenever(repositoryMock.findConsecutiveProvenBlobs(any())).thenReturn(
SafeFuture.completedFuture(
listOf(
baseBlobAndBatchCounters,
lastBlobAndBatchCounters
)
)
lastBlobAndBatchCounters,
),
),
)
cache.findConsecutiveProvenBlobs(expectedEndBLockNumber.toLong())

View File

@@ -22,12 +22,12 @@ class ForkChoiceUpdaterImplTest {
fun dispatchFinalizedBlockNotification_allClientsSuccess() {
val mockClient1 = mock<RollupForkChoiceUpdatedClient>()
whenever(
mockClient1.rollupForkChoiceUpdated(any())
mockClient1.rollupForkChoiceUpdated(any()),
)
.thenReturn(SafeFuture.completedFuture(Ok(RollupForkChoiceUpdatedResponse("success"))))
val mockClient2 = mock<RollupForkChoiceUpdatedClient>()
whenever(
mockClient2.rollupForkChoiceUpdated(any())
mockClient2.rollupForkChoiceUpdated(any()),
)
.thenReturn(SafeFuture.completedFuture(Ok(RollupForkChoiceUpdatedResponse("success"))))
@@ -43,12 +43,12 @@ class ForkChoiceUpdaterImplTest {
fun dispatchFinalizedBlockNotification_someClientsFail() {
val mockClient1 = mock<RollupForkChoiceUpdatedClient>()
whenever(
mockClient1.rollupForkChoiceUpdated(any())
mockClient1.rollupForkChoiceUpdated(any()),
)
.thenReturn(SafeFuture.completedFuture(Ok(RollupForkChoiceUpdatedResponse("success"))))
val mockClient2 = mock<RollupForkChoiceUpdatedClient>()
whenever(
mockClient2.rollupForkChoiceUpdated(any())
mockClient2.rollupForkChoiceUpdated(any()),
)
.thenReturn(SafeFuture.completedFuture(Err(ErrorResponse(RollupForkChoiceUpdatedError.UNKNOWN, ""))))

View File

@@ -17,7 +17,7 @@ class SimpleCompositeSafeFutureHandlerTest {
handler2Calls.add("handler2:$value")
SafeFuture.failedFuture(RuntimeException("Handler 2 failed"))
},
{ value: Long -> SafeFuture.completedFuture(handler3Calls.add("handler3:$value")) }
{ value: Long -> SafeFuture.completedFuture(handler3Calls.add("handler3:$value")) },
)
SimpleCompositeSafeFutureHandler(handlers).invoke(123)
@@ -34,8 +34,11 @@ class SimpleCompositeSafeFutureHandlerTest {
val handler3Calls = mutableListOf<String>()
val handlers = listOf(
{ value: Long -> SafeFuture.completedFuture(handler1Calls.add("handler1:$value")) },
{ value: Long -> handler2Calls.add("handler2:$value"); throw RuntimeException("Forced error") },
{ value: Long -> SafeFuture.completedFuture(handler3Calls.add("handler3:$value")) }
{ value: Long ->
handler2Calls.add("handler2:$value")
throw RuntimeException("Forced error")
},
{ value: Long -> SafeFuture.completedFuture(handler3Calls.add("handler3:$value")) },
)
SimpleCompositeSafeFutureHandler(handlers).invoke(123)

View File

@@ -5,7 +5,7 @@ import net.consensys.zkevm.coordinator.clients.ProverClient
import tech.pegasys.teku.infrastructure.async.SafeFuture
class StartBlockNumberBasedSwitchPredicate<ProofRequest>(
private val switchStartBlockNumberInclusive: ULong
private val switchStartBlockNumberInclusive: ULong,
) where ProofRequest : BlockInterval {
fun invoke(proofRequest: ProofRequest): Boolean = proofRequest.startBlockNumber >= switchStartBlockNumberInclusive
}
@@ -13,7 +13,7 @@ class StartBlockNumberBasedSwitchPredicate<ProofRequest>(
class ABProverClientRouter<ProofRequest, ProofResponse>(
private val proverA: ProverClient<ProofRequest, ProofResponse>,
private val proverB: ProverClient<ProofRequest, ProofResponse>,
private val switchToProverBPredicate: (ProofRequest) -> Boolean
private val switchToProverBPredicate: (ProofRequest) -> Boolean,
) : ProverClient<ProofRequest, ProofResponse> {
override fun requestProof(proofRequest: ProofRequest): SafeFuture<ProofResponse> {

View File

@@ -6,13 +6,13 @@ import kotlin.time.Duration
data class ProversConfig(
val proverA: ProverConfig,
val switchBlockNumberInclusive: ULong?,
val proverB: ProverConfig?
val proverB: ProverConfig?,
)
data class ProverConfig(
val execution: FileBasedProverConfig,
val blobCompression: FileBasedProverConfig,
val proofAggregation: FileBasedProverConfig
val proofAggregation: FileBasedProverConfig,
)
data class FileBasedProverConfig(
@@ -21,5 +21,5 @@ data class FileBasedProverConfig(
val inprogressProvingSuffixPattern: String,
val inprogressRequestWritingSuffix: String,
val pollingInterval: Duration,
val pollingTimeout: Duration
val pollingTimeout: Duration,
)

View File

@@ -28,13 +28,13 @@ import tech.pegasys.teku.infrastructure.async.SafeFuture
class FileBasedBlobCompressionProverClientV2(
val config: FileBasedProverConfig,
val vertx: Vertx,
jsonObjectMapper: ObjectMapper = JsonSerialization.proofResponseMapperV1
jsonObjectMapper: ObjectMapper = JsonSerialization.proofResponseMapperV1,
) :
GenericFileBasedProverClient<
BlobCompressionProofRequest,
BlobCompressionProof,
BlobCompressionProofJsonRequest,
BlobCompressionProofJsonResponse
BlobCompressionProofJsonResponse,
>(
config = config,
vertx = vertx,
@@ -42,7 +42,7 @@ class FileBasedBlobCompressionProverClientV2(
fileReader = FileReader(
vertx,
jsonObjectMapper,
BlobCompressionProofJsonResponse::class.java
BlobCompressionProofJsonResponse::class.java,
),
requestFileNameProvider = CompressionProofRequestFileNameProvider,
responseFileNameProvider = CompressionProofResponseFileNameProvider,
@@ -50,7 +50,7 @@ class FileBasedBlobCompressionProverClientV2(
requestMapper = FileBasedBlobCompressionProverClientV2::requestDtoMapper,
responseMapper = BlobCompressionProofJsonResponse::toDomainObject,
proofTypeLabel = "blob",
log = LogManager.getLogger(this::class.java)
log = LogManager.getLogger(this::class.java),
),
BlobCompressionProverClientV2 {
@@ -59,7 +59,7 @@ class FileBasedBlobCompressionProverClientV2(
return ProofIndex(
startBlockNumber = request.startBlockNumber,
endBlockNumber = request.endBlockNumber,
hash = request.expectedShnarfResult.expectedShnarf
hash = request.expectedShnarfResult.expectedShnarf,
)
}

View File

@@ -26,7 +26,7 @@ data class BatchExecutionProofRequestDto(
val tracesEngineVersion: String,
val type2StateManagerVersion: String?,
val zkStateMerkleProof: ArrayNode,
val blocksData: List<RlpBridgeLogsDto>
val blocksData: List<RlpBridgeLogsDto>,
)
data class RlpBridgeLogsDto(val rlp: String, val bridgeLogs: List<BridgeLogsDto>)
@@ -40,7 +40,7 @@ data class BridgeLogsDto(
val blockNumber: String,
val address: String,
val data: String,
val topics: List<String>
val topics: List<String>,
) {
companion object {
fun fromDomainObject(ethLog: EthLog): BridgeLogsDto {
@@ -53,14 +53,14 @@ data class BridgeLogsDto(
blockNumber = ethLog.blockNumber.toHexString(),
address = ethLog.address.encodeHex(),
data = ethLog.data.encodeHex(),
topics = ethLog.topics.map { it.encodeHex() }
topics = ethLog.topics.map { it.encodeHex() },
)
}
}
}
internal class ExecutionProofRequestDtoMapper(
private val encoder: BlockEncoder = BlockRLPEncoder
private val encoder: BlockEncoder = BlockRLPEncoder,
) : (BatchExecutionProofRequestV1) -> SafeFuture<BatchExecutionProofRequestDto> {
override fun invoke(request: BatchExecutionProofRequestV1): SafeFuture<BatchExecutionProofRequestDto> {
val blocksData = request.blocks.map { block ->
@@ -79,8 +79,8 @@ internal class ExecutionProofRequestDtoMapper(
tracesEngineVersion = request.tracesResponse.tracesEngineVersion,
type2StateManagerVersion = request.type2StateData.zkStateManagerVersion,
zkStateMerkleProof = request.type2StateData.zkStateMerkleProof,
blocksData = blocksData
)
blocksData = blocksData,
),
)
}
}
@@ -105,15 +105,15 @@ class FileBasedExecutionProverClientV2(
executionProofRequestFileNameProvider: ProverFileNameProvider =
ExecutionProofRequestFileNameProvider(
tracesVersion = tracesVersion,
stateManagerVersion = stateManagerVersion
stateManagerVersion = stateManagerVersion,
),
executionProofResponseFileNameProvider: ProverFileNameProvider = ExecutionProofResponseFileNameProvider
executionProofResponseFileNameProvider: ProverFileNameProvider = ExecutionProofResponseFileNameProvider,
) :
GenericFileBasedProverClient<
BatchExecutionProofRequestV1,
BatchExecutionProofResponse,
BatchExecutionProofRequestDto,
Any
Any,
>(
config = config,
vertx = vertx,
@@ -125,19 +125,19 @@ class FileBasedExecutionProverClientV2(
requestMapper = ExecutionProofRequestDtoMapper(),
responseMapper = { throw UnsupportedOperationException("Batch execution proof response shall not be parsed!") },
proofTypeLabel = "batch",
log = LogManager.getLogger(FileBasedExecutionProverClientV2::class.java)
log = LogManager.getLogger(FileBasedExecutionProverClientV2::class.java),
),
ExecutionProverClientV2 {
override fun parseResponse(
responseFilePath: Path,
proofIndex: ProofIndex
proofIndex: ProofIndex,
): SafeFuture<BatchExecutionProofResponse> {
return SafeFuture.completedFuture(
BatchExecutionProofResponse(
startBlockNumber = proofIndex.startBlockNumber,
endBlockNumber = proofIndex.endBlockNumber
)
endBlockNumber = proofIndex.endBlockNumber,
),
)
}
}

View File

@@ -21,13 +21,13 @@ data class AggregationProofRequestDto(
val compressionProofs: List<String>,
val parentAggregationLastBlockTimestamp: Long,
val parentAggregationLastL1RollingHashMessageNumber: Long,
val parentAggregationLastL1RollingHash: String
val parentAggregationLastL1RollingHash: String,
) {
companion object {
fun fromDomainObject(
proofsToAggregate: ProofsToAggregate,
executionProofResponseFileNameProvider: ProverFileNameProvider,
compressionProofResponseFileNameProvider: ProverFileNameProvider
compressionProofResponseFileNameProvider: ProverFileNameProvider,
): AggregationProofRequestDto {
val executionProofsResponseFiles = proofsToAggregate.executionProofs
.toIntervalList()
@@ -35,8 +35,8 @@ data class AggregationProofRequestDto(
executionProofResponseFileNameProvider.getFileName(
ProofIndex(
startBlockNumber = blockInterval.startBlockNumber,
endBlockNumber = blockInterval.endBlockNumber
)
endBlockNumber = blockInterval.endBlockNumber,
),
)
}
@@ -46,8 +46,8 @@ data class AggregationProofRequestDto(
ProofIndex(
startBlockNumber = it.startBlockNumber,
endBlockNumber = it.endBlockNumber,
hash = it.hash
)
hash = it.hash,
),
)
}
@@ -57,7 +57,7 @@ data class AggregationProofRequestDto(
parentAggregationLastBlockTimestamp = proofsToAggregate.parentAggregationLastBlockTimestamp.epochSeconds,
parentAggregationLastL1RollingHashMessageNumber =
proofsToAggregate.parentAggregationLastL1RollingHashMessageNumber.toLong(),
parentAggregationLastL1RollingHash = proofsToAggregate.parentAggregationLastL1RollingHash.encodeHex()
parentAggregationLastL1RollingHash = proofsToAggregate.parentAggregationLastL1RollingHash.encodeHex(),
)
}
}
@@ -65,15 +65,15 @@ data class AggregationProofRequestDto(
internal class AggregationRequestDtoMapper(
private val executionProofResponseFileNameProvider: ProverFileNameProvider,
private val compressionProofResponseFileNameProvider: ProverFileNameProvider
private val compressionProofResponseFileNameProvider: ProverFileNameProvider,
) : (ProofsToAggregate) -> SafeFuture<AggregationProofRequestDto> {
override fun invoke(proofsToAggregate: ProofsToAggregate): SafeFuture<AggregationProofRequestDto> {
return SafeFuture.completedFuture(
AggregationProofRequestDto.fromDomainObject(
proofsToAggregate,
executionProofResponseFileNameProvider,
compressionProofResponseFileNameProvider
)
compressionProofResponseFileNameProvider,
),
)
}
}
@@ -95,13 +95,13 @@ class FileBasedProofAggregationClientV2(
hashFunction: HashFunction = Sha256HashFunction(),
executionProofResponseFileNameProvider: ProverFileNameProvider = ExecutionProofResponseFileNameProvider,
compressionProofResponseFileNameProvider: ProverFileNameProvider = CompressionProofResponseFileNameProvider,
jsonObjectMapper: ObjectMapper = JsonSerialization.proofResponseMapperV1
jsonObjectMapper: ObjectMapper = JsonSerialization.proofResponseMapperV1,
) :
GenericFileBasedProverClient<
ProofsToAggregate,
ProofToFinalize,
AggregationProofRequestDto,
ProofToFinalizeJsonResponse
ProofToFinalizeJsonResponse,
>(
config = config,
vertx = vertx,
@@ -109,18 +109,18 @@ class FileBasedProofAggregationClientV2(
fileReader = FileReader(
vertx,
jsonObjectMapper,
ProofToFinalizeJsonResponse::class.java
ProofToFinalizeJsonResponse::class.java,
),
requestFileNameProvider = AggregationProofFileNameProvider,
responseFileNameProvider = AggregationProofFileNameProvider,
proofIndexProvider = createProofIndexProviderFn(hashFunction),
requestMapper = AggregationRequestDtoMapper(
executionProofResponseFileNameProvider = executionProofResponseFileNameProvider,
compressionProofResponseFileNameProvider = compressionProofResponseFileNameProvider
compressionProofResponseFileNameProvider = compressionProofResponseFileNameProvider,
),
responseMapper = ProofToFinalizeJsonResponse::toDomainObject,
proofTypeLabel = "aggregation",
log = LogManager.getLogger(this::class.java)
log = LogManager.getLogger(this::class.java),
),
ProofAggregationProverClientV2 {
@@ -128,20 +128,20 @@ class FileBasedProofAggregationClientV2(
fun createProofIndexProviderFn(
hashFunction: HashFunction,
executionProofResponseFileNameProvider: ProverFileNameProvider = ExecutionProofResponseFileNameProvider,
compressionProofResponseFileNameProvider: ProverFileNameProvider = CompressionProofResponseFileNameProvider
compressionProofResponseFileNameProvider: ProverFileNameProvider = CompressionProofResponseFileNameProvider,
): (ProofsToAggregate) -> ProofIndex {
return { request: ProofsToAggregate ->
val requestDto = AggregationProofRequestDto.fromDomainObject(
proofsToAggregate = request,
executionProofResponseFileNameProvider = executionProofResponseFileNameProvider,
compressionProofResponseFileNameProvider = compressionProofResponseFileNameProvider
compressionProofResponseFileNameProvider = compressionProofResponseFileNameProvider,
)
val hash = hashRequest(hashFunction, requestDto)
ProofIndex(
startBlockNumber = request.startBlockNumber,
endBlockNumber = request.endBlockNumber,
hash = hash
hash = hash,
)
}
}

View File

@@ -28,13 +28,13 @@ open class GenericFileBasedProverClient<Request, Response, RequestDto, ResponseD
private val responseFileNameProvider: ProverFileNameProvider,
private val fileMonitor: FileMonitor = FileMonitor(
vertx,
FileMonitor.Config(config.pollingInterval, config.pollingTimeout)
FileMonitor.Config(config.pollingInterval, config.pollingTimeout),
),
private val proofIndexProvider: (Request) -> ProofIndex = ::blockIntervalProofIndex,
private val requestMapper: (Request) -> SafeFuture<RequestDto>,
private val responseMapper: (ResponseDto) -> Response,
private val proofTypeLabel: String,
private val log: Logger = LogManager.getLogger(GenericFileBasedProverClient::class.java)
private val log: Logger = LogManager.getLogger(GenericFileBasedProverClient::class.java),
) : Supplier<Number>
where Request : BlockInterval,
Response : Any,
@@ -62,7 +62,7 @@ open class GenericFileBasedProverClient<Request, Response, RequestDto, ResponseD
"request already proven: {}={} reusedResponse={}",
proofTypeLabel,
proofIndex.intervalString(),
responseFilePath
responseFilePath,
)
SafeFuture.completedFuture(responseFilePath)
} else {
@@ -74,7 +74,7 @@ open class GenericFileBasedProverClient<Request, Response, RequestDto, ResponseD
"request already in file system: {}={} reusedRequest={}",
proofTypeLabel,
proofIndex.intervalString(),
requestFileFound
requestFileFound,
)
SafeFuture.completedFuture(Unit)
} else {
@@ -83,7 +83,7 @@ open class GenericFileBasedProverClient<Request, Response, RequestDto, ResponseD
fileWriter.write(
proofRequestDto,
requestFilePath,
config.inprogressRequestWritingSuffix
config.inprogressRequestWritingSuffix,
).thenApply {
Unit
}
@@ -104,13 +104,13 @@ open class GenericFileBasedProverClient<Request, Response, RequestDto, ResponseD
proofTypeLabel,
proofIndex.intervalString(),
it.message,
it
it,
)
}
}
private fun waitForResponse(
responseFilePath: Path
responseFilePath: Path,
): SafeFuture<Path> {
return fileMonitor.monitor(responseFilePath).thenCompose {
if (it is Err) {
@@ -130,17 +130,17 @@ open class GenericFileBasedProverClient<Request, Response, RequestDto, ResponseD
}
private fun findRequestFileIfAlreadyInFileSystem(
requestFileName: String
requestFileName: String,
): SafeFuture<String?> {
return fileMonitor.findFile(
directory = config.requestsDirectory,
pattern = inProgressFilePattern(requestFileName, config.inprogressProvingSuffixPattern)
pattern = inProgressFilePattern(requestFileName, config.inprogressProvingSuffixPattern),
)
}
protected open fun parseResponse(
responseFilePath: Path,
proofIndex: ProofIndex
proofIndex: ProofIndex,
): SafeFuture<Response> {
return fileReader.read(responseFilePath)
.thenCompose { result ->
@@ -152,7 +152,7 @@ open class GenericFileBasedProverClient<Request, Response, RequestDto, ResponseD
log.error(
"Failed to read response file={} errorMessage={}",
responseFilePath,
errorResponse.message
errorResponse.message,
)
}
}
@@ -165,13 +165,13 @@ open class GenericFileBasedProverClient<Request, Response, RequestDto, ResponseD
fun <R : BlockInterval> blockIntervalProofIndex(request: R): ProofIndex {
return ProofIndex(
startBlockNumber = request.startBlockNumber,
endBlockNumber = request.endBlockNumber
endBlockNumber = request.endBlockNumber,
)
}
fun createDirectoryIfNotExists(
directory: Path,
log: Logger = LogManager.getLogger(GenericFileBasedProverClient::class.java)
log: Logger = LogManager.getLogger(GenericFileBasedProverClient::class.java),
) {
try {
if (directory.notExists()) {

Some files were not shown because too many files have changed in this diff Show More