mirror of
https://github.com/vacp2p/linea-monorepo.git
synced 2026-01-08 03:43:56 -05:00
[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:
@@ -29,7 +29,7 @@ class LineaL1FinalizationTagUpdaterPlugin : BesuPlugin {
|
|||||||
service = LineaL1FinalizationUpdaterService(
|
service = LineaL1FinalizationUpdaterService(
|
||||||
vertx,
|
vertx,
|
||||||
cliOptions.getConfig(),
|
cliOptions.getConfig(),
|
||||||
LineaBesuEngineBlockTagUpdater(blockchainService)
|
LineaBesuEngineBlockTagUpdater(blockchainService),
|
||||||
)
|
)
|
||||||
service.start()
|
service.start()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import kotlin.time.Duration.Companion.seconds
|
|||||||
|
|
||||||
data class FinalizationUpdatePollerConfig(
|
data class FinalizationUpdatePollerConfig(
|
||||||
val pollingInterval: Duration = 12.seconds,
|
val pollingInterval: Duration = 12.seconds,
|
||||||
val blockTag: BlockParameter
|
val blockTag: BlockParameter,
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
require(pollingInterval >= 0.seconds) {
|
require(pollingInterval >= 0.seconds) {
|
||||||
@@ -30,18 +30,18 @@ class FinalizationUpdatePoller(
|
|||||||
private val config: FinalizationUpdatePollerConfig,
|
private val config: FinalizationUpdatePollerConfig,
|
||||||
private val lineaRollup: Web3JLineaRollupSmartContractClientReadOnly,
|
private val lineaRollup: Web3JLineaRollupSmartContractClientReadOnly,
|
||||||
private val finalizationHandler: (ULong) -> CompletableFuture<*>,
|
private val finalizationHandler: (ULong) -> CompletableFuture<*>,
|
||||||
private val log: Logger = LogManager.getLogger(FinalizationUpdatePoller::class.java)
|
private val log: Logger = LogManager.getLogger(FinalizationUpdatePoller::class.java),
|
||||||
) : PeriodicPollingService(
|
) : PeriodicPollingService(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
pollingIntervalMs = config.pollingInterval.inWholeMilliseconds,
|
pollingIntervalMs = config.pollingInterval.inWholeMilliseconds,
|
||||||
log = log
|
log = log,
|
||||||
) {
|
) {
|
||||||
private val lastFinalizationRef: AtomicReference<ULong> = AtomicReference(null)
|
private val lastFinalizationRef: AtomicReference<ULong> = AtomicReference(null)
|
||||||
|
|
||||||
override fun action(): SafeFuture<*> {
|
override fun action(): SafeFuture<*> {
|
||||||
return AsyncRetryer.retry(
|
return AsyncRetryer.retry(
|
||||||
vertx,
|
vertx,
|
||||||
backoffDelay = config.pollingInterval
|
backoffDelay = config.pollingInterval,
|
||||||
) {
|
) {
|
||||||
lineaRollup.finalizedL2BlockNumber(config.blockTag)
|
lineaRollup.finalizedL2BlockNumber(config.blockTag)
|
||||||
.thenCompose { lineaFinalizedBlockNumber ->
|
.thenCompose { lineaFinalizedBlockNumber ->
|
||||||
@@ -61,7 +61,7 @@ class FinalizationUpdatePoller(
|
|||||||
if (error.cause is UnsupportedOperationException) {
|
if (error.cause is UnsupportedOperationException) {
|
||||||
log.error(
|
log.error(
|
||||||
"\"setFinalizedBlock\" and \"setSafeBlock\" methods are not supported in the hosting Besu client, " +
|
"\"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()
|
super.stop()
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class LineaBesuEngineBlockTagUpdater(private val blockchainService: BlockchainSe
|
|||||||
log.info(
|
log.info(
|
||||||
"Linea safe/finalized block update: blockNumber={} blockHash={}",
|
"Linea safe/finalized block update: blockNumber={} blockHash={}",
|
||||||
finalizedBlockNumber,
|
finalizedBlockNumber,
|
||||||
blockHash
|
blockHash,
|
||||||
)
|
)
|
||||||
blockchainService.setSafeBlock(blockHash)
|
blockchainService.setSafeBlock(blockHash)
|
||||||
blockchainService.setFinalizedBlock(blockHash)
|
blockchainService.setFinalizedBlock(blockHash)
|
||||||
@@ -40,7 +40,7 @@ class LineaBesuEngineBlockTagUpdater(private val blockchainService: BlockchainSe
|
|||||||
log.error(
|
log.error(
|
||||||
"Linea safe/finalized block update failure: Method not supported or not enabled for PoS network: " +
|
"Linea safe/finalized block update failure: Method not supported or not enabled for PoS network: " +
|
||||||
"setFinalizedBlock and setSafeBlock",
|
"setFinalizedBlock and setSafeBlock",
|
||||||
e
|
e,
|
||||||
)
|
)
|
||||||
throw e
|
throw e
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@@ -54,7 +54,7 @@ class LineaBesuEngineBlockTagUpdater(private val blockchainService: BlockchainSe
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun lineaUpdateFinalizedBlockV1(
|
override fun lineaUpdateFinalizedBlockV1(
|
||||||
finalizedBlockNumber: Long
|
finalizedBlockNumber: Long,
|
||||||
) {
|
) {
|
||||||
val updateSuccess = setFinalizedAndSafeBlock(finalizedBlockNumber)
|
val updateSuccess = setFinalizedAndSafeBlock(finalizedBlockNumber)
|
||||||
log.debug("Linea safe/finalized block update: blockNumber={} success={}", finalizedBlockNumber, updateSuccess)
|
log.debug("Linea safe/finalized block update: blockNumber={} success={}", finalizedBlockNumber, updateSuccess)
|
||||||
@@ -62,10 +62,10 @@ class LineaBesuEngineBlockTagUpdater(private val blockchainService: BlockchainSe
|
|||||||
}
|
}
|
||||||
|
|
||||||
class LineaL1FinalizationUpdater(
|
class LineaL1FinalizationUpdater(
|
||||||
private val engineBlockTagUpdater: EngineBlockTagUpdater
|
private val engineBlockTagUpdater: EngineBlockTagUpdater,
|
||||||
) {
|
) {
|
||||||
fun handleL1Finalization(
|
fun handleL1Finalization(
|
||||||
finalizedBlockNumber: ULong
|
finalizedBlockNumber: ULong,
|
||||||
): CompletableFuture<Unit> {
|
): CompletableFuture<Unit> {
|
||||||
runCatching {
|
runCatching {
|
||||||
engineBlockTagUpdater
|
engineBlockTagUpdater
|
||||||
@@ -80,28 +80,28 @@ class LineaL1FinalizationUpdater(
|
|||||||
class LineaL1FinalizationUpdaterService(
|
class LineaL1FinalizationUpdaterService(
|
||||||
vertx: Vertx,
|
vertx: Vertx,
|
||||||
config: PluginConfig,
|
config: PluginConfig,
|
||||||
engineBlockTagUpdater: EngineBlockTagUpdater
|
engineBlockTagUpdater: EngineBlockTagUpdater,
|
||||||
) : LongRunningService {
|
) : LongRunningService {
|
||||||
private val web3j = Web3j.build(
|
private val web3j = Web3j.build(
|
||||||
HttpService(
|
HttpService(
|
||||||
config.l1RpcEndpoint.toString(),
|
config.l1RpcEndpoint.toString(),
|
||||||
okHttpClientBuilder(LogManager.getLogger("clients.l1")).build()
|
okHttpClientBuilder(LogManager.getLogger("clients.l1")).build(),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
private val lineaRollup = Web3JLineaRollupSmartContractClientReadOnly(
|
private val lineaRollup = Web3JLineaRollupSmartContractClientReadOnly(
|
||||||
contractAddress = config.l1SmartContractAddress.toHexString(),
|
contractAddress = config.l1SmartContractAddress.toHexString(),
|
||||||
web3j = web3j
|
web3j = web3j,
|
||||||
)
|
)
|
||||||
private val updater = LineaL1FinalizationUpdater(engineBlockTagUpdater)
|
private val updater = LineaL1FinalizationUpdater(engineBlockTagUpdater)
|
||||||
private val poller = FinalizationUpdatePoller(
|
private val poller = FinalizationUpdatePoller(
|
||||||
vertx,
|
vertx,
|
||||||
FinalizationUpdatePollerConfig(
|
FinalizationUpdatePollerConfig(
|
||||||
pollingInterval = config.l1PollingInterval,
|
pollingInterval = config.l1PollingInterval,
|
||||||
blockTag = BlockParameter.Tag.FINALIZED
|
blockTag = BlockParameter.Tag.FINALIZED,
|
||||||
),
|
),
|
||||||
lineaRollup,
|
lineaRollup,
|
||||||
updater::handleL1Finalization,
|
updater::handleL1Finalization,
|
||||||
LogManager.getLogger(FinalizationUpdatePoller::class.java)
|
LogManager.getLogger(FinalizationUpdatePoller::class.java),
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun start(): CompletableFuture<Unit> {
|
override fun start(): CompletableFuture<Unit> {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import kotlin.time.toKotlinDuration
|
|||||||
data class PluginConfig(
|
data class PluginConfig(
|
||||||
val l1SmartContractAddress: Address,
|
val l1SmartContractAddress: Address,
|
||||||
val l1RpcEndpoint: URL,
|
val l1RpcEndpoint: URL,
|
||||||
val l1PollingInterval: kotlin.time.Duration
|
val l1PollingInterval: kotlin.time.Duration,
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
require(l1PollingInterval >= 1.seconds) { "Polling interval=$l1PollingInterval must be greater that 1s." }
|
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"],
|
names = ["--plugin-linea-l1-smart-contract-address"],
|
||||||
description = ["L1 smart contract address"],
|
description = ["L1 smart contract address"],
|
||||||
required = true,
|
required = true,
|
||||||
converter = [AddressConverter::class]
|
converter = [AddressConverter::class],
|
||||||
)
|
)
|
||||||
lateinit var l1SmartContractAddress: Address
|
lateinit var l1SmartContractAddress: Address
|
||||||
|
|
||||||
@CommandLine.Option(
|
@CommandLine.Option(
|
||||||
names = ["--plugin-linea-l1-rpc-endpoint"],
|
names = ["--plugin-linea-l1-rpc-endpoint"],
|
||||||
description = ["L1 RPC endpoint"],
|
description = ["L1 RPC endpoint"],
|
||||||
required = true
|
required = true,
|
||||||
)
|
)
|
||||||
lateinit var l1RpcEndpoint: String
|
lateinit var l1RpcEndpoint: String
|
||||||
|
|
||||||
@CommandLine.Option(
|
@CommandLine.Option(
|
||||||
names = ["--plugin-linea-l1-polling-interval"],
|
names = ["--plugin-linea-l1-polling-interval"],
|
||||||
description = ["L1 polling interval"],
|
description = ["L1 polling interval"],
|
||||||
required = false
|
required = false,
|
||||||
)
|
)
|
||||||
var l1PollingInterval: Duration = Duration.ofSeconds(12)
|
var l1PollingInterval: Duration = Duration.ofSeconds(12)
|
||||||
|
|
||||||
@@ -45,14 +45,14 @@ class PluginCliOptions {
|
|||||||
return PluginConfig(
|
return PluginConfig(
|
||||||
l1SmartContractAddress = l1SmartContractAddress,
|
l1SmartContractAddress = l1SmartContractAddress,
|
||||||
l1RpcEndpoint = URI(l1RpcEndpoint).toURL(),
|
l1RpcEndpoint = URI(l1RpcEndpoint).toURL(),
|
||||||
l1PollingInterval = l1PollingInterval.toKotlinDuration()
|
l1PollingInterval = l1PollingInterval.toKotlinDuration(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
class AddressConverter : CommandLine.ITypeConverter<Address> {
|
class AddressConverter : CommandLine.ITypeConverter<Address> {
|
||||||
override fun convert(value: String): Address {
|
override fun convert(value: String): Address {
|
||||||
return Address.fromHexString(value) ?: throw CommandLine.TypeConversionException(
|
return Address.fromHexString(value) ?: throw CommandLine.TypeConversionException(
|
||||||
"Invalid address: $value"
|
"Invalid address: $value",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import kotlin.time.Duration.Companion.seconds
|
|||||||
|
|
||||||
class FakeEngineBlockTagUpdater : EngineBlockTagUpdater {
|
class FakeEngineBlockTagUpdater : EngineBlockTagUpdater {
|
||||||
override fun lineaUpdateFinalizedBlockV1(
|
override fun lineaUpdateFinalizedBlockV1(
|
||||||
finalizedBlockNumber: Long
|
finalizedBlockNumber: Long,
|
||||||
) {
|
) {
|
||||||
println("Linea finalized block update: blockNumber=$finalizedBlockNumber")
|
println("Linea finalized block update: blockNumber=$finalizedBlockNumber")
|
||||||
}
|
}
|
||||||
@@ -23,7 +23,7 @@ fun main() {
|
|||||||
val config = PluginConfig(
|
val config = PluginConfig(
|
||||||
l1RpcEndpoint = URI("https://mainnet.infura.io/v3/$infuraAppKey").toURL(),
|
l1RpcEndpoint = URI("https://mainnet.infura.io/v3/$infuraAppKey").toURL(),
|
||||||
l1SmartContractAddress = Address.fromHexString("0xd19d4B5d358258f05D7B411E21A1460D11B0876F"),
|
l1SmartContractAddress = Address.fromHexString("0xd19d4B5d358258f05D7B411E21A1460D11B0876F"),
|
||||||
l1PollingInterval = 1.seconds
|
l1PollingInterval = 1.seconds,
|
||||||
)
|
)
|
||||||
val service = LineaL1FinalizationUpdaterService(vertx, config, FakeEngineBlockTagUpdater())
|
val service = LineaL1FinalizationUpdaterService(vertx, config, FakeEngineBlockTagUpdater())
|
||||||
service.start().get()
|
service.start().get()
|
||||||
|
|||||||
@@ -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 {
|
build {
|
||||||
dependsOn checkLicense
|
dependsOn checkLicense
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import tech.pegasys.teku.infrastructure.async.SafeFuture
|
|||||||
|
|
||||||
data class StateRecoveryStatus(
|
data class StateRecoveryStatus(
|
||||||
val headBlockNumber: ULong,
|
val headBlockNumber: ULong,
|
||||||
val stateRecoverStartBlockNumber: ULong?
|
val stateRecoverStartBlockNumber: ULong?,
|
||||||
)
|
)
|
||||||
interface ExecutionLayerClient {
|
interface ExecutionLayerClient {
|
||||||
fun getBlockNumberAndHash(blockParameter: BlockParameter): SafeFuture<BlockNumberAndHash>
|
fun getBlockNumberAndHash(blockParameter: BlockParameter): SafeFuture<BlockNumberAndHash>
|
||||||
|
|||||||
@@ -24,20 +24,20 @@ class InMemoryRecoveryStatus : RecoveryStatusPersistence {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class FileBasedRecoveryStatusPersistence(
|
class FileBasedRecoveryStatusPersistence(
|
||||||
filePath: Path
|
filePath: Path,
|
||||||
) : RecoveryStatusPersistence {
|
) : RecoveryStatusPersistence {
|
||||||
// A little future proofing in case we need to change the file format in the future
|
// A little future proofing in case we need to change the file format in the future
|
||||||
private enum class FileVersion {
|
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(
|
private data class RecoveryStatusEnvelopeDto(
|
||||||
val version: FileVersion,
|
val version: FileVersion,
|
||||||
val recoveryStatus: RecoveryStatusV1Dto?
|
val recoveryStatus: RecoveryStatusV1Dto?,
|
||||||
)
|
)
|
||||||
|
|
||||||
private data class RecoveryStatusV1Dto(
|
private data class RecoveryStatusV1Dto(
|
||||||
val recoveryStartBlockNumber: ULong
|
val recoveryStartBlockNumber: ULong,
|
||||||
)
|
)
|
||||||
private val objectMapper = jacksonObjectMapper()
|
private val objectMapper = jacksonObjectMapper()
|
||||||
private val file = filePath.toFile()
|
private val file = filePath.toFile()
|
||||||
@@ -46,8 +46,8 @@ class FileBasedRecoveryStatusPersistence(
|
|||||||
private fun saveToFile(status: RecoveryStatusV1Dto?) {
|
private fun saveToFile(status: RecoveryStatusV1Dto?) {
|
||||||
file.writeText(
|
file.writeText(
|
||||||
objectMapper.writeValueAsString(
|
objectMapper.writeValueAsString(
|
||||||
RecoveryStatusEnvelopeDto(FileVersion.V1, status)
|
RecoveryStatusEnvelopeDto(FileVersion.V1, status),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class FileRecoveryStatusPersistenceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `should return null when no recovery start block number is saved`(
|
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"))
|
val recoveryStatusPersistence = FileBasedRecoveryStatusPersistence(tempDir.resolve("recovery-status.json"))
|
||||||
assertThat(recoveryStatusPersistence.getRecoveryStartBlockNumber()).isNull()
|
assertThat(recoveryStatusPersistence.getRecoveryStartBlockNumber()).isNull()
|
||||||
@@ -21,7 +21,7 @@ class FileRecoveryStatusPersistenceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `should return the saved recovery start block number`(
|
fun `should return the saved recovery start block number`(
|
||||||
@TempDir tempDir: Path
|
@TempDir tempDir: Path,
|
||||||
) {
|
) {
|
||||||
FileBasedRecoveryStatusPersistence(tempDir.resolve("recovery-status.json"))
|
FileBasedRecoveryStatusPersistence(tempDir.resolve("recovery-status.json"))
|
||||||
.also { persistence ->
|
.also { persistence ->
|
||||||
@@ -46,7 +46,7 @@ class FileRecoveryStatusPersistenceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `shall throw when it cannot create the file`(
|
fun `shall throw when it cannot create the file`(
|
||||||
@TempDir tempDir: Path
|
@TempDir tempDir: Path,
|
||||||
) {
|
) {
|
||||||
val dirWithoutWritePermissions = tempDir.resolve("dir-without-write-permissions")
|
val dirWithoutWritePermissions = tempDir.resolve("dir-without-write-permissions")
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ class FileRecoveryStatusPersistenceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `should throw error when file version is not supported`(
|
fun `should throw error when file version is not supported`(
|
||||||
@TempDir tempDir: Path
|
@TempDir tempDir: Path,
|
||||||
) {
|
) {
|
||||||
val invalidJsonPayload = """
|
val invalidJsonPayload = """
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ data class BlockHeaderFromL1RecoveredData(
|
|||||||
val coinbase: ByteArray,
|
val coinbase: ByteArray,
|
||||||
val blockTimestamp: Instant,
|
val blockTimestamp: Instant,
|
||||||
val gasLimit: ULong,
|
val gasLimit: ULong,
|
||||||
val difficulty: ULong
|
val difficulty: ULong,
|
||||||
) {
|
) {
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
@@ -51,7 +51,7 @@ data class BlockHeaderFromL1RecoveredData(
|
|||||||
|
|
||||||
data class BlockFromL1RecoveredData(
|
data class BlockFromL1RecoveredData(
|
||||||
val header: BlockHeaderFromL1RecoveredData,
|
val header: BlockHeaderFromL1RecoveredData,
|
||||||
val transactions: List<TransactionFromL1RecoveredData>
|
val transactions: List<TransactionFromL1RecoveredData>,
|
||||||
) {
|
) {
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
|
|||||||
@@ -14,12 +14,12 @@ data class TransactionFromL1RecoveredData(
|
|||||||
val to: ByteArray?,
|
val to: ByteArray?,
|
||||||
val value: BigInteger,
|
val value: BigInteger,
|
||||||
val data: ByteArray?,
|
val data: ByteArray?,
|
||||||
val accessList: List<AccessTuple>?
|
val accessList: List<AccessTuple>?,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
data class AccessTuple(
|
data class AccessTuple(
|
||||||
val address: ByteArray,
|
val address: ByteArray,
|
||||||
val storageKeys: List<ByteArray>
|
val storageKeys: List<ByteArray>,
|
||||||
) {
|
) {
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
|
|||||||
@@ -24,18 +24,18 @@ interface BlobDecompressorAndDeserializer {
|
|||||||
*/
|
*/
|
||||||
fun decompress(
|
fun decompress(
|
||||||
startBlockNumber: ULong,
|
startBlockNumber: ULong,
|
||||||
blobs: List<ByteArray>
|
blobs: List<ByteArray>,
|
||||||
): SafeFuture<List<BlockFromL1RecoveredData>>
|
): SafeFuture<List<BlockFromL1RecoveredData>>
|
||||||
}
|
}
|
||||||
|
|
||||||
data class BlockHeaderStaticFields(
|
data class BlockHeaderStaticFields(
|
||||||
val coinbase: ByteArray,
|
val coinbase: ByteArray,
|
||||||
val gasLimit: ULong = 2_000_000_000UL,
|
val gasLimit: ULong = 2_000_000_000UL,
|
||||||
val difficulty: ULong = 2UL
|
val difficulty: ULong = 2UL,
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
val localDev = BlockHeaderStaticFields(
|
val localDev = BlockHeaderStaticFields(
|
||||||
coinbase = "0x6d976c9b8ceee705d4fe8699b44e5eb58242f484".decodeHex()
|
coinbase = "0x6d976c9b8ceee705d4fe8699b44e5eb58242f484".decodeHex(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,11 +69,11 @@ class BlobDecompressorToDomainV1(
|
|||||||
val staticFields: BlockHeaderStaticFields,
|
val staticFields: BlockHeaderStaticFields,
|
||||||
val vertx: Vertx,
|
val vertx: Vertx,
|
||||||
val decoder: BinaryDecoder<Block> = BesuRlpBlobDecoder,
|
val decoder: BinaryDecoder<Block> = BesuRlpBlobDecoder,
|
||||||
val logger: Logger = LogManager.getLogger(BlobDecompressorToDomainV1::class.java)
|
val logger: Logger = LogManager.getLogger(BlobDecompressorToDomainV1::class.java),
|
||||||
) : BlobDecompressorAndDeserializer {
|
) : BlobDecompressorAndDeserializer {
|
||||||
override fun decompress(
|
override fun decompress(
|
||||||
startBlockNumber: ULong,
|
startBlockNumber: ULong,
|
||||||
blobs: List<ByteArray>
|
blobs: List<ByteArray>,
|
||||||
): SafeFuture<List<BlockFromL1RecoveredData>> {
|
): SafeFuture<List<BlockFromL1RecoveredData>> {
|
||||||
var blockNumber = startBlockNumber
|
var blockNumber = startBlockNumber
|
||||||
val startTime = Clock.System.now()
|
val startTime = Clock.System.now()
|
||||||
@@ -89,7 +89,7 @@ class BlobDecompressorToDomainV1(
|
|||||||
coinbase = staticFields.coinbase,
|
coinbase = staticFields.coinbase,
|
||||||
blockTimestamp = Instant.fromEpochSeconds(block.header.timestamp),
|
blockTimestamp = Instant.fromEpochSeconds(block.header.timestamp),
|
||||||
gasLimit = this.staticFields.gasLimit,
|
gasLimit = this.staticFields.gasLimit,
|
||||||
difficulty = this.staticFields.difficulty
|
difficulty = this.staticFields.difficulty,
|
||||||
)
|
)
|
||||||
val transactions = block.body.transactions.map { transaction ->
|
val transactions = block.body.transactions.map { transaction ->
|
||||||
TransactionFromL1RecoveredData(
|
TransactionFromL1RecoveredData(
|
||||||
@@ -106,14 +106,14 @@ class BlobDecompressorToDomainV1(
|
|||||||
accessList = transaction.accessList.getOrNull()?.map { accessTuple ->
|
accessList = transaction.accessList.getOrNull()?.map { accessTuple ->
|
||||||
TransactionFromL1RecoveredData.AccessTuple(
|
TransactionFromL1RecoveredData.AccessTuple(
|
||||||
address = accessTuple.address.toArray(),
|
address = accessTuple.address.toArray(),
|
||||||
storageKeys = accessTuple.storageKeys.map { it.toArray() }
|
storageKeys = accessTuple.storageKeys.map { it.toArray() },
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
BlockFromL1RecoveredData(
|
BlockFromL1RecoveredData(
|
||||||
header = header,
|
header = header,
|
||||||
transactions = transactions
|
transactions = transactions,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}.thenPeek {
|
}.thenPeek {
|
||||||
@@ -122,7 +122,7 @@ class BlobDecompressorToDomainV1(
|
|||||||
"blobs decompressed and serialized: duration={} blobsCount={} blocks={}",
|
"blobs decompressed and serialized: duration={} blobsCount={} blocks={}",
|
||||||
endTime - startTime,
|
endTime - startTime,
|
||||||
blobs.size,
|
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>> {
|
private fun decodeBlocksAsync(blocksRLP: ByteArray): SafeFuture<List<Block>> {
|
||||||
return vertx.executeBlocking(
|
return vertx.executeBlocking(
|
||||||
Callable { RLP.decodeList(blocksRLP).map(decoder::decode) },
|
Callable { RLP.decodeList(blocksRLP).map(decoder::decode) },
|
||||||
false
|
false,
|
||||||
)
|
)
|
||||||
.onFailure(logger::error)
|
.onFailure(logger::error)
|
||||||
.toSafeFuture()
|
.toSafeFuture()
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import kotlin.time.Duration.Companion.seconds
|
|||||||
|
|
||||||
data class ImportResult(
|
data class ImportResult(
|
||||||
val blockNumber: ULong,
|
val blockNumber: ULong,
|
||||||
val zkStateRootHash: ByteArray
|
val zkStateRootHash: ByteArray,
|
||||||
) {
|
) {
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
@@ -39,7 +39,7 @@ class BlockImporterAndStateVerifierV1(
|
|||||||
private val vertx: Vertx,
|
private val vertx: Vertx,
|
||||||
private val elClient: ExecutionLayerClient,
|
private val elClient: ExecutionLayerClient,
|
||||||
private val stateManagerClient: StateManagerClientV1,
|
private val stateManagerClient: StateManagerClientV1,
|
||||||
private val stateManagerImportTimeoutPerBlock: Duration
|
private val stateManagerImportTimeoutPerBlock: Duration,
|
||||||
) : BlockImporterAndStateVerifier {
|
) : BlockImporterAndStateVerifier {
|
||||||
override fun importBlocks(blocks: List<BlockFromL1RecoveredData>): SafeFuture<ImportResult> {
|
override fun importBlocks(blocks: List<BlockFromL1RecoveredData>): SafeFuture<ImportResult> {
|
||||||
val sortedBlocks = blocks.sortedBy { it.header.blockNumber }
|
val sortedBlocks = blocks.sortedBy { it.header.blockNumber }
|
||||||
@@ -49,20 +49,20 @@ class BlockImporterAndStateVerifierV1(
|
|||||||
.thenCompose {
|
.thenCompose {
|
||||||
getBlockStateRootHash(
|
getBlockStateRootHash(
|
||||||
blockNumber = lastBlockNumber,
|
blockNumber = lastBlockNumber,
|
||||||
timeout = stateManagerImportTimeoutPerBlock.times(blocks.size)
|
timeout = stateManagerImportTimeoutPerBlock.times(blocks.size),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.thenApply { stateRootHash ->
|
.thenApply { stateRootHash ->
|
||||||
ImportResult(
|
ImportResult(
|
||||||
blockNumber = lastBlockNumber,
|
blockNumber = lastBlockNumber,
|
||||||
zkStateRootHash = stateRootHash
|
zkStateRootHash = stateRootHash,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getBlockStateRootHash(
|
private fun getBlockStateRootHash(
|
||||||
blockNumber: ULong,
|
blockNumber: ULong,
|
||||||
timeout: Duration
|
timeout: Duration,
|
||||||
): SafeFuture<ByteArray> {
|
): SafeFuture<ByteArray> {
|
||||||
return AsyncRetryer
|
return AsyncRetryer
|
||||||
.retry(
|
.retry(
|
||||||
@@ -70,7 +70,7 @@ class BlockImporterAndStateVerifierV1(
|
|||||||
backoffDelay = 1.seconds,
|
backoffDelay = 1.seconds,
|
||||||
timeout = timeout,
|
timeout = timeout,
|
||||||
stopRetriesPredicate = { headBlockNumber -> headBlockNumber >= blockNumber },
|
stopRetriesPredicate = { headBlockNumber -> headBlockNumber >= blockNumber },
|
||||||
action = { stateManagerClient.rollupGetHeadBlockNumber() }
|
action = { stateManagerClient.rollupGetHeadBlockNumber() },
|
||||||
)
|
)
|
||||||
.thenCompose {
|
.thenCompose {
|
||||||
stateManagerClient.rollupGetStateMerkleProof(BlockInterval(blockNumber, blockNumber))
|
stateManagerClient.rollupGetStateMerkleProof(BlockInterval(blockNumber, blockNumber))
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import tech.pegasys.teku.infrastructure.async.SafeFuture
|
|||||||
data class DataSubmittedV3(
|
data class DataSubmittedV3(
|
||||||
val parentShnarf: ByteArray,
|
val parentShnarf: ByteArray,
|
||||||
val shnarf: ByteArray,
|
val shnarf: ByteArray,
|
||||||
val finalStateRootHash: ByteArray
|
val finalStateRootHash: ByteArray,
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
val topic = "0x55f4c645c36aa5cd3f443d6be44d7a7a5df9d2100d7139dfc69d4289ee072319"
|
val topic = "0x55f4c645c36aa5cd3f443d6be44d7a7a5df9d2100d7139dfc69d4289ee072319"
|
||||||
@@ -22,9 +22,9 @@ data class DataSubmittedV3(
|
|||||||
event = DataSubmittedV3(
|
event = DataSubmittedV3(
|
||||||
parentShnarf = ethLog.data.sliceOf32(0),
|
parentShnarf = ethLog.data.sliceOf32(0),
|
||||||
shnarf = ethLog.topics[1],
|
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,
|
override val endBlockNumber: ULong,
|
||||||
val shnarf: ByteArray,
|
val shnarf: ByteArray,
|
||||||
val parentStateRootHash: ByteArray,
|
val parentStateRootHash: ByteArray,
|
||||||
val finalStateRootHash: ByteArray
|
val finalStateRootHash: ByteArray,
|
||||||
) : BlockInterval {
|
) : BlockInterval {
|
||||||
companion object {
|
companion object {
|
||||||
val topic = "0xa0262dc79e4ccb71ceac8574ae906311ae338aa4a2044fd4ec4b99fad5ab60cb"
|
val topic = "0xa0262dc79e4ccb71ceac8574ae906311ae338aa4a2044fd4ec4b99fad5ab60cb"
|
||||||
@@ -81,9 +81,9 @@ data class DataFinalizedV3(
|
|||||||
endBlockNumber = ethLog.topics[2].toULongFromLast8Bytes(),
|
endBlockNumber = ethLog.topics[2].toULongFromLast8Bytes(),
|
||||||
shnarf = ethLog.topics[3],
|
shnarf = ethLog.topics[3],
|
||||||
parentStateRootHash = dataBytes.sliceOf32(sliceNumber = 0),
|
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(
|
data class FinalizationAndDataEventsV3(
|
||||||
val dataSubmittedEvents: List<EthLogEvent<DataSubmittedV3>>,
|
val dataSubmittedEvents: List<EthLogEvent<DataSubmittedV3>>,
|
||||||
val dataFinalizedEvent: EthLogEvent<DataFinalizedV3>
|
val dataFinalizedEvent: EthLogEvent<DataFinalizedV3>,
|
||||||
)
|
)
|
||||||
|
|
||||||
interface LineaRollupSubmissionEventsClient {
|
interface LineaRollupSubmissionEventsClient {
|
||||||
fun findFinalizationAndDataSubmissionV3Events(
|
fun findFinalizationAndDataSubmissionV3Events(
|
||||||
fromL1BlockNumber: BlockParameter,
|
fromL1BlockNumber: BlockParameter,
|
||||||
finalizationStartBlockNumber: ULong
|
finalizationStartBlockNumber: ULong,
|
||||||
): SafeFuture<FinalizationAndDataEventsV3?>
|
): SafeFuture<FinalizationAndDataEventsV3?>
|
||||||
|
|
||||||
fun findFinalizationAndDataSubmissionV3EventsContainingL2BlockNumber(
|
fun findFinalizationAndDataSubmissionV3EventsContainingL2BlockNumber(
|
||||||
fromL1BlockNumber: BlockParameter,
|
fromL1BlockNumber: BlockParameter,
|
||||||
l2BlockNumber: ULong
|
l2BlockNumber: ULong,
|
||||||
): SafeFuture<FinalizationAndDataEventsV3?>
|
): SafeFuture<FinalizationAndDataEventsV3?>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class LineaSubmissionEventsClientImpl(
|
|||||||
private val logsSearcher: EthLogsSearcher,
|
private val logsSearcher: EthLogsSearcher,
|
||||||
private val smartContractAddress: String,
|
private val smartContractAddress: String,
|
||||||
private val l1LatestSearchBlock: BlockParameter = BlockParameter.Tag.FINALIZED,
|
private val l1LatestSearchBlock: BlockParameter = BlockParameter.Tag.FINALIZED,
|
||||||
private val logsBlockChunkSize: Int
|
private val logsBlockChunkSize: Int,
|
||||||
) : LineaRollupSubmissionEventsClient {
|
) : LineaRollupSubmissionEventsClient {
|
||||||
init {
|
init {
|
||||||
require(logsBlockChunkSize > 0) { "logsBlockChunkSize=$logsBlockChunkSize must be greater than 0" }
|
require(logsBlockChunkSize > 0) { "logsBlockChunkSize=$logsBlockChunkSize must be greater than 0" }
|
||||||
@@ -21,7 +21,7 @@ class LineaSubmissionEventsClientImpl(
|
|||||||
|
|
||||||
private fun findDataFinalizedEventContainingBlock(
|
private fun findDataFinalizedEventContainingBlock(
|
||||||
fromBlock: BlockParameter,
|
fromBlock: BlockParameter,
|
||||||
l2BlockNumber: ULong
|
l2BlockNumber: ULong,
|
||||||
): SafeFuture<EthLogEvent<DataFinalizedV3>?> {
|
): SafeFuture<EthLogEvent<DataFinalizedV3>?> {
|
||||||
return logsSearcher.findLog(
|
return logsSearcher.findLog(
|
||||||
fromBlock = fromBlock,
|
fromBlock = fromBlock,
|
||||||
@@ -36,18 +36,18 @@ class LineaSubmissionEventsClientImpl(
|
|||||||
l2BlockNumber > event.endBlockNumber -> SearchDirection.FORWARD
|
l2BlockNumber > event.endBlockNumber -> SearchDirection.FORWARD
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
).thenApply { it?.let { DataFinalizedV3.fromEthLog(it) } }
|
).thenApply { it?.let { DataFinalizedV3.fromEthLog(it) } }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun findFinalizationAndDataSubmissionV3Events(
|
override fun findFinalizationAndDataSubmissionV3Events(
|
||||||
fromL1BlockNumber: BlockParameter,
|
fromL1BlockNumber: BlockParameter,
|
||||||
finalizationStartBlockNumber: ULong
|
finalizationStartBlockNumber: ULong,
|
||||||
): SafeFuture<FinalizationAndDataEventsV3?> {
|
): SafeFuture<FinalizationAndDataEventsV3?> {
|
||||||
return findDataFinalizedV3Event(
|
return findDataFinalizedV3Event(
|
||||||
fromL1BlockNumber = fromL1BlockNumber,
|
fromL1BlockNumber = fromL1BlockNumber,
|
||||||
toL1BlockNumber = l1LatestSearchBlock,
|
toL1BlockNumber = l1LatestSearchBlock,
|
||||||
startBlockNumber = finalizationStartBlockNumber
|
startBlockNumber = finalizationStartBlockNumber,
|
||||||
)
|
)
|
||||||
.thenCompose { finalizationEvent ->
|
.thenCompose { finalizationEvent ->
|
||||||
finalizationEvent
|
finalizationEvent
|
||||||
@@ -63,7 +63,7 @@ class LineaSubmissionEventsClientImpl(
|
|||||||
|
|
||||||
override fun findFinalizationAndDataSubmissionV3EventsContainingL2BlockNumber(
|
override fun findFinalizationAndDataSubmissionV3EventsContainingL2BlockNumber(
|
||||||
fromL1BlockNumber: BlockParameter,
|
fromL1BlockNumber: BlockParameter,
|
||||||
l2BlockNumber: ULong
|
l2BlockNumber: ULong,
|
||||||
): SafeFuture<FinalizationAndDataEventsV3?> {
|
): SafeFuture<FinalizationAndDataEventsV3?> {
|
||||||
return findDataFinalizedEventContainingBlock(fromL1BlockNumber, l2BlockNumber)
|
return findDataFinalizedEventContainingBlock(fromL1BlockNumber, l2BlockNumber)
|
||||||
.thenCompose { finalizationEvent ->
|
.thenCompose { finalizationEvent ->
|
||||||
@@ -82,7 +82,7 @@ class LineaSubmissionEventsClientImpl(
|
|||||||
fromL1BlockNumber: BlockParameter,
|
fromL1BlockNumber: BlockParameter,
|
||||||
toL1BlockNumber: BlockParameter,
|
toL1BlockNumber: BlockParameter,
|
||||||
startBlockNumber: ULong? = null,
|
startBlockNumber: ULong? = null,
|
||||||
endBlockNumber: ULong? = null
|
endBlockNumber: ULong? = null,
|
||||||
): SafeFuture<EthLogEvent<DataFinalizedV3>?> {
|
): SafeFuture<EthLogEvent<DataFinalizedV3>?> {
|
||||||
assert(startBlockNumber != null || endBlockNumber != null) {
|
assert(startBlockNumber != null || endBlockNumber != null) {
|
||||||
"Either startBlockNumber or endBlockNumber must be provided"
|
"Either startBlockNumber or endBlockNumber must be provided"
|
||||||
@@ -104,8 +104,8 @@ class LineaSubmissionEventsClientImpl(
|
|||||||
topics = listOf(
|
topics = listOf(
|
||||||
DataFinalizedV3.topic,
|
DataFinalizedV3.topic,
|
||||||
startBlockNumber?.toHexStringUInt256(),
|
startBlockNumber?.toHexStringUInt256(),
|
||||||
endBlockNumber?.toHexStringUInt256()
|
endBlockNumber?.toHexStringUInt256(),
|
||||||
)
|
),
|
||||||
).thenCompose { rawLogs ->
|
).thenCompose { rawLogs ->
|
||||||
val finalizedEvents = rawLogs.map(DataFinalizedV3::fromEthLog)
|
val finalizedEvents = rawLogs.map(DataFinalizedV3::fromEthLog)
|
||||||
|
|
||||||
@@ -122,7 +122,7 @@ class LineaSubmissionEventsClientImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun findAggregationDataSubmittedV3Events(
|
private fun findAggregationDataSubmittedV3Events(
|
||||||
finalizationEvent: EthLogEvent<DataFinalizedV3>
|
finalizationEvent: EthLogEvent<DataFinalizedV3>,
|
||||||
): SafeFuture<List<EthLogEvent<DataSubmittedV3>>> {
|
): SafeFuture<List<EthLogEvent<DataSubmittedV3>>> {
|
||||||
val dataEvents = mutableListOf<EthLogEvent<DataSubmittedV3>>()
|
val dataEvents = mutableListOf<EthLogEvent<DataSubmittedV3>>()
|
||||||
val futureResult = SafeFuture<List<EthLogEvent<DataSubmittedV3>>>()
|
val futureResult = SafeFuture<List<EthLogEvent<DataSubmittedV3>>>()
|
||||||
@@ -140,7 +140,7 @@ class LineaSubmissionEventsClientImpl(
|
|||||||
findDataSubmittedV3EventByShnarf(
|
findDataSubmittedV3EventByShnarf(
|
||||||
fromL1BlockParameter = BlockParameter.Tag.EARLIEST,
|
fromL1BlockParameter = BlockParameter.Tag.EARLIEST,
|
||||||
tol1BlockParameter = dataSubmission.log.blockNumber.toLong().toBlockParameter(),
|
tol1BlockParameter = dataSubmission.log.blockNumber.toLong().toBlockParameter(),
|
||||||
shnarf = dataSubmission.event.parentShnarf
|
shnarf = dataSubmission.event.parentShnarf,
|
||||||
).thenPeek(::fetchParentDataSubmission)
|
).thenPeek(::fetchParentDataSubmission)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,7 +148,7 @@ class LineaSubmissionEventsClientImpl(
|
|||||||
getDataSubmittedV3EventByShnarf(
|
getDataSubmittedV3EventByShnarf(
|
||||||
fromL1BlockParameter = BlockParameter.Tag.EARLIEST,
|
fromL1BlockParameter = BlockParameter.Tag.EARLIEST,
|
||||||
tol1BlockParameter = finalizationEvent.log.blockNumber.toLong().toBlockParameter(),
|
tol1BlockParameter = finalizationEvent.log.blockNumber.toLong().toBlockParameter(),
|
||||||
shnarf = finalizationEvent.event.shnarf
|
shnarf = finalizationEvent.event.shnarf,
|
||||||
).thenPeek(::fetchParentDataSubmission)
|
).thenPeek(::fetchParentDataSubmission)
|
||||||
|
|
||||||
return futureResult
|
return futureResult
|
||||||
@@ -157,7 +157,7 @@ class LineaSubmissionEventsClientImpl(
|
|||||||
private fun getDataSubmittedV3EventByShnarf(
|
private fun getDataSubmittedV3EventByShnarf(
|
||||||
fromL1BlockParameter: BlockParameter,
|
fromL1BlockParameter: BlockParameter,
|
||||||
tol1BlockParameter: BlockParameter,
|
tol1BlockParameter: BlockParameter,
|
||||||
shnarf: ByteArray
|
shnarf: ByteArray,
|
||||||
): SafeFuture<EthLogEvent<DataSubmittedV3>> {
|
): SafeFuture<EthLogEvent<DataSubmittedV3>> {
|
||||||
return findDataSubmittedV3EventByShnarf(fromL1BlockParameter, tol1BlockParameter, shnarf)
|
return findDataSubmittedV3EventByShnarf(fromL1BlockParameter, tol1BlockParameter, shnarf)
|
||||||
.thenApply { event ->
|
.thenApply { event ->
|
||||||
@@ -168,7 +168,7 @@ class LineaSubmissionEventsClientImpl(
|
|||||||
private fun findDataSubmittedV3EventByShnarf(
|
private fun findDataSubmittedV3EventByShnarf(
|
||||||
fromL1BlockParameter: BlockParameter,
|
fromL1BlockParameter: BlockParameter,
|
||||||
tol1BlockParameter: BlockParameter,
|
tol1BlockParameter: BlockParameter,
|
||||||
shnarf: ByteArray
|
shnarf: ByteArray,
|
||||||
): SafeFuture<EthLogEvent<DataSubmittedV3>?> {
|
): SafeFuture<EthLogEvent<DataSubmittedV3>?> {
|
||||||
return logsSearcher
|
return logsSearcher
|
||||||
.getLogs(
|
.getLogs(
|
||||||
@@ -177,8 +177,8 @@ class LineaSubmissionEventsClientImpl(
|
|||||||
address = smartContractAddress,
|
address = smartContractAddress,
|
||||||
topics = listOf(
|
topics = listOf(
|
||||||
DataSubmittedV3.topic,
|
DataSubmittedV3.topic,
|
||||||
shnarf.encodeHex()
|
shnarf.encodeHex(),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
.thenApply { rawLogs ->
|
.thenApply { rawLogs ->
|
||||||
val events = rawLogs.map(DataSubmittedV3::fromEthLog)
|
val events = rawLogs.map(DataSubmittedV3::fromEthLog)
|
||||||
|
|||||||
@@ -12,28 +12,28 @@ import kotlin.time.Duration.Companion.seconds
|
|||||||
class LookBackBlockHashesFetcher(
|
class LookBackBlockHashesFetcher(
|
||||||
private val vertx: Vertx,
|
private val vertx: Vertx,
|
||||||
private val elClient: ExecutionLayerClient,
|
private val elClient: ExecutionLayerClient,
|
||||||
private val submissionsFetcher: SubmissionsFetchingTask
|
private val submissionsFetcher: SubmissionsFetchingTask,
|
||||||
) {
|
) {
|
||||||
fun getLookBackHashes(
|
fun getLookBackHashes(
|
||||||
status: StateRecoveryStatus
|
status: StateRecoveryStatus,
|
||||||
): SafeFuture<Map<ULong, ByteArray>> {
|
): SafeFuture<Map<ULong, ByteArray>> {
|
||||||
val intervals = lookbackFetchingIntervals(
|
val intervals = lookbackFetchingIntervals(
|
||||||
headBlockNumber = status.headBlockNumber,
|
headBlockNumber = status.headBlockNumber,
|
||||||
recoveryStartBlockNumber = status.stateRecoverStartBlockNumber,
|
recoveryStartBlockNumber = status.stateRecoverStartBlockNumber,
|
||||||
lookbackWindow = 256UL
|
lookbackWindow = 256UL,
|
||||||
)
|
)
|
||||||
|
|
||||||
return SafeFuture.collectAll(
|
return SafeFuture.collectAll(
|
||||||
listOf(
|
listOf(
|
||||||
intervals.elInterval?.let(::getLookBackHashesFromLocalEl) ?: SafeFuture.completedFuture(emptyMap()),
|
intervals.elInterval?.let(::getLookBackHashesFromLocalEl) ?: SafeFuture.completedFuture(emptyMap()),
|
||||||
intervals.l1Interval?.let(::getLookBackHashesFromL1) ?: SafeFuture.completedFuture(emptyMap())
|
intervals.l1Interval?.let(::getLookBackHashesFromL1) ?: SafeFuture.completedFuture(emptyMap()),
|
||||||
).stream()
|
).stream(),
|
||||||
)
|
)
|
||||||
.thenApply { (blockHashesFromEl, blockHashesFromL1) -> blockHashesFromEl + blockHashesFromL1 }
|
.thenApply { (blockHashesFromEl, blockHashesFromL1) -> blockHashesFromEl + blockHashesFromL1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLookBackHashesFromLocalEl(
|
fun getLookBackHashesFromLocalEl(
|
||||||
blockInterval: BlockInterval
|
blockInterval: BlockInterval,
|
||||||
): SafeFuture<Map<ULong, ByteArray>> {
|
): SafeFuture<Map<ULong, ByteArray>> {
|
||||||
return SafeFuture
|
return SafeFuture
|
||||||
.collectAll(blockInterval.blocksRange.map { elClient.getBlockNumberAndHash(it.toBlockParameter()) }.stream())
|
.collectAll(blockInterval.blocksRange.map { elClient.getBlockNumberAndHash(it.toBlockParameter()) }.stream())
|
||||||
@@ -43,7 +43,7 @@ class LookBackBlockHashesFetcher(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getLookBackHashesFromL1(
|
fun getLookBackHashesFromL1(
|
||||||
blockInterval: BlockInterval
|
blockInterval: BlockInterval,
|
||||||
): SafeFuture<Map<ULong, ByteArray>> {
|
): SafeFuture<Map<ULong, ByteArray>> {
|
||||||
return AsyncRetryer.retry(
|
return AsyncRetryer.retry(
|
||||||
vertx,
|
vertx,
|
||||||
@@ -51,7 +51,7 @@ class LookBackBlockHashesFetcher(
|
|||||||
stopRetriesPredicate = { submissions ->
|
stopRetriesPredicate = { submissions ->
|
||||||
submissions.isNotEmpty() &&
|
submissions.isNotEmpty() &&
|
||||||
submissions.last().submissionEvents.dataFinalizedEvent.event.endBlockNumber >= blockInterval.endBlockNumber
|
submissions.last().submissionEvents.dataFinalizedEvent.event.endBlockNumber >= blockInterval.endBlockNumber
|
||||||
}
|
},
|
||||||
) {
|
) {
|
||||||
// get the data without removing it from the queue
|
// get the data without removing it from the queue
|
||||||
// it must still be in the queue until is imported to the EL
|
// it must still be in the queue until is imported to the EL
|
||||||
@@ -75,7 +75,7 @@ class LookBackBlockHashesFetcher(
|
|||||||
|
|
||||||
fun shallIncreaseQueueLimit(
|
fun shallIncreaseQueueLimit(
|
||||||
availableSubmissions: List<SubmissionEventsAndData<BlockFromL1RecoveredData>>,
|
availableSubmissions: List<SubmissionEventsAndData<BlockFromL1RecoveredData>>,
|
||||||
blockInterval: BlockInterval
|
blockInterval: BlockInterval,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (availableSubmissions.isEmpty()) {
|
if (availableSubmissions.isEmpty()) {
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import linea.kotlin.minusCoercingUnderflow
|
|||||||
fun startBlockToFetchFromL1(
|
fun startBlockToFetchFromL1(
|
||||||
headBlockNumber: ULong,
|
headBlockNumber: ULong,
|
||||||
recoveryStartBlockNumber: ULong?,
|
recoveryStartBlockNumber: ULong?,
|
||||||
lookbackWindow: ULong
|
lookbackWindow: ULong,
|
||||||
): ULong {
|
): ULong {
|
||||||
if (recoveryStartBlockNumber == null) {
|
if (recoveryStartBlockNumber == null) {
|
||||||
return headBlockNumber + 1UL
|
return headBlockNumber + 1UL
|
||||||
@@ -19,24 +19,24 @@ fun startBlockToFetchFromL1(
|
|||||||
|
|
||||||
data class FetchingIntervals(
|
data class FetchingIntervals(
|
||||||
val elInterval: BlockInterval?,
|
val elInterval: BlockInterval?,
|
||||||
val l1Interval: BlockInterval?
|
val l1Interval: BlockInterval?,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun lookbackFetchingIntervals(
|
fun lookbackFetchingIntervals(
|
||||||
headBlockNumber: ULong,
|
headBlockNumber: ULong,
|
||||||
recoveryStartBlockNumber: ULong?,
|
recoveryStartBlockNumber: ULong?,
|
||||||
lookbackWindow: ULong
|
lookbackWindow: ULong,
|
||||||
): FetchingIntervals {
|
): FetchingIntervals {
|
||||||
if (recoveryStartBlockNumber == null || recoveryStartBlockNumber > headBlockNumber) {
|
if (recoveryStartBlockNumber == null || recoveryStartBlockNumber > headBlockNumber) {
|
||||||
return FetchingIntervals(
|
return FetchingIntervals(
|
||||||
l1Interval = null,
|
l1Interval = null,
|
||||||
elInterval = BlockInterval(headBlockNumber.minusCoercingUnderflow(lookbackWindow - 1UL), headBlockNumber)
|
elInterval = BlockInterval(headBlockNumber.minusCoercingUnderflow(lookbackWindow - 1UL), headBlockNumber),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (headBlockNumber - lookbackWindow > recoveryStartBlockNumber) {
|
if (headBlockNumber - lookbackWindow > recoveryStartBlockNumber) {
|
||||||
return FetchingIntervals(
|
return FetchingIntervals(
|
||||||
l1Interval = BlockInterval(headBlockNumber.minusCoercingUnderflow(lookbackWindow - 1UL), headBlockNumber),
|
l1Interval = BlockInterval(headBlockNumber.minusCoercingUnderflow(lookbackWindow - 1UL), headBlockNumber),
|
||||||
elInterval = null
|
elInterval = null,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ fun lookbackFetchingIntervals(
|
|||||||
l1Interval = BlockInterval(recoveryStartBlockNumber, headBlockNumber),
|
l1Interval = BlockInterval(recoveryStartBlockNumber, headBlockNumber),
|
||||||
elInterval = BlockInterval(
|
elInterval = BlockInterval(
|
||||||
headBlockNumber.minusCoercingUnderflow(lookbackWindow - 1UL),
|
headBlockNumber.minusCoercingUnderflow(lookbackWindow - 1UL),
|
||||||
recoveryStartBlockNumber - 1UL
|
recoveryStartBlockNumber - 1UL,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class StateRecoveryApp(
|
|||||||
private val transactionDetailsClient: TransactionDetailsClient,
|
private val transactionDetailsClient: TransactionDetailsClient,
|
||||||
private val blockHeaderStaticFields: BlockHeaderStaticFields,
|
private val blockHeaderStaticFields: BlockHeaderStaticFields,
|
||||||
// configs
|
// configs
|
||||||
private val config: Config
|
private val config: Config,
|
||||||
) : LongRunningService {
|
) : LongRunningService {
|
||||||
data class Config(
|
data class Config(
|
||||||
val smartContractAddress: String,
|
val smartContractAddress: String,
|
||||||
@@ -43,7 +43,7 @@ class StateRecoveryApp(
|
|||||||
* this is meant for testing purposes, not production
|
* this is meant for testing purposes, not production
|
||||||
*/
|
*/
|
||||||
val overridingRecoveryStartBlockNumber: ULong? = null,
|
val overridingRecoveryStartBlockNumber: ULong? = null,
|
||||||
val debugForceSyncStopBlockNumber: ULong? = null
|
val debugForceSyncStopBlockNumber: ULong? = null,
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
val lineaMainnet = Config(
|
val lineaMainnet = Config(
|
||||||
@@ -53,7 +53,7 @@ class StateRecoveryApp(
|
|||||||
l1LatestSearchBlock = BlockParameter.Tag.FINALIZED,
|
l1LatestSearchBlock = BlockParameter.Tag.FINALIZED,
|
||||||
l1PollingInterval = 12.seconds,
|
l1PollingInterval = 12.seconds,
|
||||||
l1getLogsChunkSize = 10_000u,
|
l1getLogsChunkSize = 10_000u,
|
||||||
executionClientPollingInterval = 2.seconds
|
executionClientPollingInterval = 2.seconds,
|
||||||
)
|
)
|
||||||
val lineaSepolia = Config(
|
val lineaSepolia = Config(
|
||||||
smartContractAddress = "0xb218f8a4bc926cf1ca7b3423c154a0d627bdb7e5",
|
smartContractAddress = "0xb218f8a4bc926cf1ca7b3423c154a0d627bdb7e5",
|
||||||
@@ -61,7 +61,7 @@ class StateRecoveryApp(
|
|||||||
l1LatestSearchBlock = BlockParameter.Tag.FINALIZED,
|
l1LatestSearchBlock = BlockParameter.Tag.FINALIZED,
|
||||||
l1PollingInterval = 12.seconds,
|
l1PollingInterval = 12.seconds,
|
||||||
l1getLogsChunkSize = 10_000u,
|
l1getLogsChunkSize = 10_000u,
|
||||||
executionClientPollingInterval = 2.seconds
|
executionClientPollingInterval = 2.seconds,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,19 +76,19 @@ class StateRecoveryApp(
|
|||||||
logsSearcher = ethLogsSearcher,
|
logsSearcher = ethLogsSearcher,
|
||||||
smartContractAddress = config.smartContractAddress,
|
smartContractAddress = config.smartContractAddress,
|
||||||
l1LatestSearchBlock = config.l1LatestSearchBlock,
|
l1LatestSearchBlock = config.l1LatestSearchBlock,
|
||||||
logsBlockChunkSize = config.l1getLogsChunkSize.toInt()
|
logsBlockChunkSize = config.l1getLogsChunkSize.toInt(),
|
||||||
)
|
)
|
||||||
private val log = LogManager.getLogger(this::class.java)
|
private val log = LogManager.getLogger(this::class.java)
|
||||||
private val blockImporterAndStateVerifier = BlockImporterAndStateVerifierV1(
|
private val blockImporterAndStateVerifier = BlockImporterAndStateVerifierV1(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
elClient = elClient,
|
elClient = elClient,
|
||||||
stateManagerClient = stateManagerClient,
|
stateManagerClient = stateManagerClient,
|
||||||
stateManagerImportTimeoutPerBlock = 2.seconds
|
stateManagerImportTimeoutPerBlock = 2.seconds,
|
||||||
)
|
)
|
||||||
private val blobDecompressor: BlobDecompressorAndDeserializer = BlobDecompressorToDomainV1(
|
private val blobDecompressor: BlobDecompressorAndDeserializer = BlobDecompressorToDomainV1(
|
||||||
decompressor = GoNativeBlobDecompressorFactory.getInstance(config.blobDecompressorVersion),
|
decompressor = GoNativeBlobDecompressorFactory.getInstance(config.blobDecompressorVersion),
|
||||||
staticFields = blockHeaderStaticFields,
|
staticFields = blockHeaderStaticFields,
|
||||||
vertx = vertx
|
vertx = vertx,
|
||||||
)
|
)
|
||||||
private val stateSynchronizerService = StateSynchronizerService(
|
private val stateSynchronizerService = StateSynchronizerService(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
@@ -100,7 +100,7 @@ class StateRecoveryApp(
|
|||||||
blobDecompressor = blobDecompressor,
|
blobDecompressor = blobDecompressor,
|
||||||
blockImporterAndStateVerifier = blockImporterAndStateVerifier,
|
blockImporterAndStateVerifier = blockImporterAndStateVerifier,
|
||||||
pollingInterval = config.l1PollingInterval,
|
pollingInterval = config.l1PollingInterval,
|
||||||
debugForceSyncStopBlockNumber = config.debugForceSyncStopBlockNumber
|
debugForceSyncStopBlockNumber = config.debugForceSyncStopBlockNumber,
|
||||||
)
|
)
|
||||||
val stateRootMismatchFound: Boolean
|
val stateRootMismatchFound: Boolean
|
||||||
get() = stateSynchronizerService.stateRootMismatchFound
|
get() = stateSynchronizerService.stateRootMismatchFound
|
||||||
@@ -119,7 +119,7 @@ class StateRecoveryApp(
|
|||||||
updateLabel,
|
updateLabel,
|
||||||
newStatus.headBlockNumber,
|
newStatus.headBlockNumber,
|
||||||
statusBeforeUpdate.stateRecoverStartBlockNumber,
|
statusBeforeUpdate.stateRecoverStartBlockNumber,
|
||||||
newStatus.stateRecoverStartBlockNumber
|
newStatus.stateRecoverStartBlockNumber,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,7 +138,7 @@ class StateRecoveryApp(
|
|||||||
log.info(
|
log.info(
|
||||||
"starting recovery mode already enabled: stateRecoverStartBlockNumber={} headBlockNumber={}",
|
"starting recovery mode already enabled: stateRecoverStartBlockNumber={} headBlockNumber={}",
|
||||||
status.stateRecoverStartBlockNumber,
|
status.stateRecoverStartBlockNumber,
|
||||||
status.headBlockNumber
|
status.headBlockNumber,
|
||||||
)
|
)
|
||||||
SafeFuture.completedFuture(Unit)
|
SafeFuture.completedFuture(Unit)
|
||||||
} else {
|
} else {
|
||||||
@@ -153,7 +153,7 @@ class StateRecoveryApp(
|
|||||||
"L1 lastFinalizedBlockNumber={}",
|
"L1 lastFinalizedBlockNumber={}",
|
||||||
stateRecoverStartBlockNumber,
|
stateRecoverStartBlockNumber,
|
||||||
status.headBlockNumber,
|
status.headBlockNumber,
|
||||||
lastFinalizedBlockNumber
|
lastFinalizedBlockNumber,
|
||||||
)
|
)
|
||||||
elClient.lineaEnableStateRecovery(stateRecoverStartBlockNumber)
|
elClient.lineaEnableStateRecovery(stateRecoverStartBlockNumber)
|
||||||
}.thenApply { }
|
}.thenApply { }
|
||||||
@@ -175,17 +175,17 @@ class StateRecoveryApp(
|
|||||||
log.info(
|
log.info(
|
||||||
"node reached recovery target block: stateRecoverStartBlockNumber={} headBlockNumber={}",
|
"node reached recovery target block: stateRecoverStartBlockNumber={} headBlockNumber={}",
|
||||||
recoveryStatus.stateRecoverStartBlockNumber,
|
recoveryStatus.stateRecoverStartBlockNumber,
|
||||||
recoveryStatus.headBlockNumber
|
recoveryStatus.headBlockNumber,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
log.info(
|
log.info(
|
||||||
"waiting for node to sync until stateRecoverStartBlockNumber={} - 1, headBlockNumber={}",
|
"waiting for node to sync until stateRecoverStartBlockNumber={} - 1, headBlockNumber={}",
|
||||||
recoveryStatus.stateRecoverStartBlockNumber,
|
recoveryStatus.stateRecoverStartBlockNumber,
|
||||||
recoveryStatus.headBlockNumber
|
recoveryStatus.headBlockNumber,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
hasReachedTargetBlock
|
hasReachedTargetBlock
|
||||||
}
|
},
|
||||||
) {
|
) {
|
||||||
elClient.lineaGetStateRecoveryStatus()
|
elClient.lineaGetStateRecoveryStatus()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ class StateSynchronizerService(
|
|||||||
private val blockImporterAndStateVerifier: BlockImporterAndStateVerifier,
|
private val blockImporterAndStateVerifier: BlockImporterAndStateVerifier,
|
||||||
private val pollingInterval: Duration,
|
private val pollingInterval: Duration,
|
||||||
private val debugForceSyncStopBlockNumber: ULong?,
|
private val debugForceSyncStopBlockNumber: ULong?,
|
||||||
private val log: Logger = LogManager.getLogger(StateSynchronizerService::class.java)
|
private val log: Logger = LogManager.getLogger(StateSynchronizerService::class.java),
|
||||||
) : PeriodicPollingService(
|
) : PeriodicPollingService(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
log = log,
|
log = log,
|
||||||
pollingIntervalMs = pollingInterval.inWholeMilliseconds
|
pollingIntervalMs = pollingInterval.inWholeMilliseconds,
|
||||||
) {
|
) {
|
||||||
@get:Synchronized
|
@get:Synchronized
|
||||||
@set:Synchronized
|
@set:Synchronized
|
||||||
@@ -48,7 +48,7 @@ class StateSynchronizerService(
|
|||||||
val l2StartBlockNumberToFetchInclusive = startBlockToFetchFromL1(
|
val l2StartBlockNumberToFetchInclusive = startBlockToFetchFromL1(
|
||||||
headBlockNumber = status.headBlockNumber,
|
headBlockNumber = status.headBlockNumber,
|
||||||
recoveryStartBlockNumber = status.stateRecoverStartBlockNumber,
|
recoveryStartBlockNumber = status.stateRecoverStartBlockNumber,
|
||||||
lookbackWindow = 256UL
|
lookbackWindow = 256UL,
|
||||||
)
|
)
|
||||||
|
|
||||||
this.blobsFetcherTask = SubmissionsFetchingTask(
|
this.blobsFetcherTask = SubmissionsFetchingTask(
|
||||||
@@ -63,7 +63,7 @@ class StateSynchronizerService(
|
|||||||
submissionEventsQueueLimit = 10,
|
submissionEventsQueueLimit = 10,
|
||||||
compressedBlobsQueueLimit = 10,
|
compressedBlobsQueueLimit = 10,
|
||||||
targetDecompressedBlobsQueueLimit = 10,
|
targetDecompressedBlobsQueueLimit = 10,
|
||||||
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber
|
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber,
|
||||||
)
|
)
|
||||||
blobsFetcherTask.start()
|
blobsFetcherTask.start()
|
||||||
}
|
}
|
||||||
@@ -91,7 +91,7 @@ class StateSynchronizerService(
|
|||||||
val loobackHasheFetcher = LookBackBlockHashesFetcher(
|
val loobackHasheFetcher = LookBackBlockHashesFetcher(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
elClient = elClient,
|
elClient = elClient,
|
||||||
submissionsFetcher = blobsFetcherTask
|
submissionsFetcher = blobsFetcherTask,
|
||||||
)
|
)
|
||||||
|
|
||||||
return this.elClient
|
return this.elClient
|
||||||
@@ -116,30 +116,30 @@ class StateSynchronizerService(
|
|||||||
if (blocksToImport.isEmpty()) {
|
if (blocksToImport.isEmpty()) {
|
||||||
log.debug(
|
log.debug(
|
||||||
"no blocks to import for finalization={}",
|
"no blocks to import for finalization={}",
|
||||||
nexFinalization.submissionEvents.dataFinalizedEvent.event
|
nexFinalization.submissionEvents.dataFinalizedEvent.event,
|
||||||
)
|
)
|
||||||
return@thenCompose SafeFuture.completedFuture(Unit)
|
return@thenCompose SafeFuture.completedFuture(Unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
importBlocksAndAssertStateroot(
|
importBlocksAndAssertStateroot(
|
||||||
decompressedBlocksToImport = blocksToImport,
|
decompressedBlocksToImport = blocksToImport,
|
||||||
dataFinalizedV3 = nexFinalization.submissionEvents.dataFinalizedEvent.event
|
dataFinalizedV3 = nexFinalization.submissionEvents.dataFinalizedEvent.event,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.thenPeek {
|
.thenPeek {
|
||||||
blobsFetcherTask.pruneQueueForElementsUpToInclusive(
|
blobsFetcherTask.pruneQueueForElementsUpToInclusive(
|
||||||
nexFinalization.submissionEvents.dataFinalizedEvent.event.endBlockNumber
|
nexFinalization.submissionEvents.dataFinalizedEvent.event.endBlockNumber,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun importBlocksAndAssertStateroot(
|
private fun importBlocksAndAssertStateroot(
|
||||||
decompressedBlocksToImport: List<BlockFromL1RecoveredData>,
|
decompressedBlocksToImport: List<BlockFromL1RecoveredData>,
|
||||||
dataFinalizedV3: DataFinalizedV3
|
dataFinalizedV3: DataFinalizedV3,
|
||||||
): SafeFuture<Unit> {
|
): SafeFuture<Unit> {
|
||||||
val blockInterval = CommonDomainFunctions.blockIntervalString(
|
val blockInterval = CommonDomainFunctions.blockIntervalString(
|
||||||
decompressedBlocksToImport.first().header.blockNumber,
|
decompressedBlocksToImport.first().header.blockNumber,
|
||||||
decompressedBlocksToImport.last().header.blockNumber
|
decompressedBlocksToImport.last().header.blockNumber,
|
||||||
)
|
)
|
||||||
log.debug("importing blocks={} from finalization={}", blockInterval, dataFinalizedV3.intervalString())
|
log.debug("importing blocks={} from finalization={}", blockInterval, dataFinalizedV3.intervalString())
|
||||||
return blockImporterAndStateVerifier
|
return blockImporterAndStateVerifier
|
||||||
@@ -151,7 +151,7 @@ class StateSynchronizerService(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun filterOutBlocksAlreadyImportedAndBeyondStopSync(
|
private fun filterOutBlocksAlreadyImportedAndBeyondStopSync(
|
||||||
blocks: List<BlockFromL1RecoveredData>
|
blocks: List<BlockFromL1RecoveredData>,
|
||||||
): SafeFuture<List<BlockFromL1RecoveredData>> {
|
): SafeFuture<List<BlockFromL1RecoveredData>> {
|
||||||
return elClient.getBlockNumberAndHash(blockParameter = BlockParameter.Tag.LATEST)
|
return elClient.getBlockNumberAndHash(blockParameter = BlockParameter.Tag.LATEST)
|
||||||
.thenApply { headBlock ->
|
.thenApply { headBlock ->
|
||||||
@@ -165,14 +165,14 @@ class StateSynchronizerService(
|
|||||||
|
|
||||||
private fun assertStateMatches(
|
private fun assertStateMatches(
|
||||||
importResult: ImportResult,
|
importResult: ImportResult,
|
||||||
finalizedV3: DataFinalizedV3
|
finalizedV3: DataFinalizedV3,
|
||||||
): SafeFuture<Unit> {
|
): SafeFuture<Unit> {
|
||||||
if (importResult.blockNumber != finalizedV3.endBlockNumber) {
|
if (importResult.blockNumber != finalizedV3.endBlockNumber) {
|
||||||
log.info(
|
log.info(
|
||||||
"cannot compare stateroot: last imported block={} finalization={} debugForceSyncStopBlockNumber={}",
|
"cannot compare stateroot: last imported block={} finalization={} debugForceSyncStopBlockNumber={}",
|
||||||
importResult.blockNumber,
|
importResult.blockNumber,
|
||||||
finalizedV3.intervalString(),
|
finalizedV3.intervalString(),
|
||||||
debugForceSyncStopBlockNumber
|
debugForceSyncStopBlockNumber,
|
||||||
)
|
)
|
||||||
if (importResult.blockNumber == debugForceSyncStopBlockNumber) {
|
if (importResult.blockNumber == debugForceSyncStopBlockNumber) {
|
||||||
// this means debugForceSyncStopBlockNumber was set and we stopped before reaching the target block
|
// this means debugForceSyncStopBlockNumber was set and we stopped before reaching the target block
|
||||||
@@ -183,7 +183,7 @@ class StateSynchronizerService(
|
|||||||
log.info(
|
log.info(
|
||||||
"state recovered up to finalization={} zkStateRootHash={}",
|
"state recovered up to finalization={} zkStateRootHash={}",
|
||||||
finalizedV3.intervalString(),
|
finalizedV3.intervalString(),
|
||||||
importResult.zkStateRootHash.encodeHex()
|
importResult.zkStateRootHash.encodeHex(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
log.error(
|
log.error(
|
||||||
@@ -193,7 +193,7 @@ class StateSynchronizerService(
|
|||||||
finalizedV3.intervalString(),
|
finalizedV3.intervalString(),
|
||||||
importResult.blockNumber,
|
importResult.blockNumber,
|
||||||
importResult.zkStateRootHash.encodeHex(),
|
importResult.zkStateRootHash.encodeHex(),
|
||||||
finalizedV3.finalStateRootHash.encodeHex()
|
finalizedV3.finalStateRootHash.encodeHex(),
|
||||||
)
|
)
|
||||||
stateRootMismatchFound = true
|
stateRootMismatchFound = true
|
||||||
this.stop()
|
this.stop()
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ internal class BlobDecompressionTask(
|
|||||||
private val rawBlobsQueue: ConcurrentLinkedQueue<SubmissionEventsAndData<ByteArray>>,
|
private val rawBlobsQueue: ConcurrentLinkedQueue<SubmissionEventsAndData<ByteArray>>,
|
||||||
private val decompressedBlocksQueue: ConcurrentLinkedQueue<SubmissionEventsAndData<BlockFromL1RecoveredData>>,
|
private val decompressedBlocksQueue: ConcurrentLinkedQueue<SubmissionEventsAndData<BlockFromL1RecoveredData>>,
|
||||||
private val decompressedFinalizationQueueLimit: Supplier<Int>,
|
private val decompressedFinalizationQueueLimit: Supplier<Int>,
|
||||||
private val log: Logger = LogManager.getLogger(SubmissionsFetchingTask::class.java)
|
private val log: Logger = LogManager.getLogger(SubmissionsFetchingTask::class.java),
|
||||||
) : PeriodicPollingService(
|
) : PeriodicPollingService(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
pollingIntervalMs = pollingInterval.inWholeMilliseconds,
|
pollingIntervalMs = pollingInterval.inWholeMilliseconds,
|
||||||
log = log
|
log = log,
|
||||||
) {
|
) {
|
||||||
override fun action(): SafeFuture<*> {
|
override fun action(): SafeFuture<*> {
|
||||||
return decompressAndDeserializeBlobs()
|
return decompressAndDeserializeBlobs()
|
||||||
@@ -38,10 +38,10 @@ internal class BlobDecompressionTask(
|
|||||||
return blobDecompressor
|
return blobDecompressor
|
||||||
.decompress(
|
.decompress(
|
||||||
startBlockNumber = submissionEventsAndData.submissionEvents.dataFinalizedEvent.event.startBlockNumber,
|
startBlockNumber = submissionEventsAndData.submissionEvents.dataFinalizedEvent.event.startBlockNumber,
|
||||||
blobs = submissionEventsAndData.data
|
blobs = submissionEventsAndData.data,
|
||||||
).thenCompose { decompressedBlocks ->
|
).thenCompose { decompressedBlocks ->
|
||||||
decompressedBlocksQueue.add(
|
decompressedBlocksQueue.add(
|
||||||
SubmissionEventsAndData(submissionEventsAndData.submissionEvents, decompressedBlocks)
|
SubmissionEventsAndData(submissionEventsAndData.submissionEvents, decompressedBlocks),
|
||||||
)
|
)
|
||||||
decompressAndDeserializeBlobs()
|
decompressAndDeserializeBlobs()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,11 +19,11 @@ internal class BlobsFetchingTask(
|
|||||||
private val submissionEventsQueue: ConcurrentLinkedQueue<FinalizationAndDataEventsV3>,
|
private val submissionEventsQueue: ConcurrentLinkedQueue<FinalizationAndDataEventsV3>,
|
||||||
private val compressedBlobsQueue: ConcurrentLinkedQueue<SubmissionEventsAndData<ByteArray>>,
|
private val compressedBlobsQueue: ConcurrentLinkedQueue<SubmissionEventsAndData<ByteArray>>,
|
||||||
private val compressedBlobsQueueLimit: Int,
|
private val compressedBlobsQueueLimit: Int,
|
||||||
private val log: Logger = LogManager.getLogger(BlobsFetchingTask::class.java)
|
private val log: Logger = LogManager.getLogger(BlobsFetchingTask::class.java),
|
||||||
) : PeriodicPollingService(
|
) : PeriodicPollingService(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
pollingIntervalMs = pollingInterval.inWholeMilliseconds,
|
pollingIntervalMs = pollingInterval.inWholeMilliseconds,
|
||||||
log = log
|
log = log,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
override fun action(): SafeFuture<*> {
|
override fun action(): SafeFuture<*> {
|
||||||
@@ -50,13 +50,13 @@ internal class BlobsFetchingTask(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun fetchBlobsOfSubmissionEvents(
|
private fun fetchBlobsOfSubmissionEvents(
|
||||||
submissionEvents: FinalizationAndDataEventsV3
|
submissionEvents: FinalizationAndDataEventsV3,
|
||||||
): SafeFuture<List<ByteArray>> {
|
): SafeFuture<List<ByteArray>> {
|
||||||
return SafeFuture.collectAll(
|
return SafeFuture.collectAll(
|
||||||
submissionEvents.dataSubmittedEvents
|
submissionEvents.dataSubmittedEvents
|
||||||
.map {
|
.map {
|
||||||
transactionDetailsClient.getBlobVersionedHashesByTransactionHash(it.log.transactionHash)
|
transactionDetailsClient.getBlobVersionedHashesByTransactionHash(it.log.transactionHash)
|
||||||
}.stream()
|
}.stream(),
|
||||||
)
|
)
|
||||||
.thenCompose { blobsVersionedHashesByTransaction ->
|
.thenCompose { blobsVersionedHashesByTransaction ->
|
||||||
blobsFetcher.fetchBlobsByHash(blobsVersionedHashesByTransaction.flatten())
|
blobsFetcher.fetchBlobsByHash(blobsVersionedHashesByTransaction.flatten())
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ internal class SubmissionEventsFetchingTask(
|
|||||||
private val submissionEventsQueue: ConcurrentLinkedQueue<FinalizationAndDataEventsV3>,
|
private val submissionEventsQueue: ConcurrentLinkedQueue<FinalizationAndDataEventsV3>,
|
||||||
private val queueLimit: Int,
|
private val queueLimit: Int,
|
||||||
private val debugForceSyncStopBlockNumber: ULong?,
|
private val debugForceSyncStopBlockNumber: ULong?,
|
||||||
private val log: Logger = LogManager.getLogger(SubmissionEventsFetchingTask::class.java)
|
private val log: Logger = LogManager.getLogger(SubmissionEventsFetchingTask::class.java),
|
||||||
) : PeriodicPollingService(
|
) : PeriodicPollingService(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
pollingIntervalMs = l1PollingInterval.inWholeMilliseconds,
|
pollingIntervalMs = l1PollingInterval.inWholeMilliseconds,
|
||||||
log = log
|
log = log,
|
||||||
) {
|
) {
|
||||||
val latestFetchedFinalization: AtomicReference<EthLogEvent<DataFinalizedV3>> = AtomicReference(null)
|
val latestFetchedFinalization: AtomicReference<EthLogEvent<DataFinalizedV3>> = AtomicReference(null)
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ internal class SubmissionEventsFetchingTask(
|
|||||||
) {
|
) {
|
||||||
log.debug(
|
log.debug(
|
||||||
"Force stop fetching submission events from L1, reached debugForceSyncStopBlockNumber={}",
|
"Force stop fetching submission events from L1, reached debugForceSyncStopBlockNumber={}",
|
||||||
debugForceSyncStopBlockNumber
|
debugForceSyncStopBlockNumber,
|
||||||
)
|
)
|
||||||
return this.stop()
|
return this.stop()
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@ internal class SubmissionEventsFetchingTask(
|
|||||||
// Queue is full, no need to fetch more
|
// Queue is full, no need to fetch more
|
||||||
log.debug(
|
log.debug(
|
||||||
"skipping fetching submission events from L1, internal queue is full size={}",
|
"skipping fetching submission events from L1, internal queue is full size={}",
|
||||||
submissionEventsQueue.size
|
submissionEventsQueue.size,
|
||||||
)
|
)
|
||||||
return SafeFuture.completedFuture(Unit)
|
return SafeFuture.completedFuture(Unit)
|
||||||
}
|
}
|
||||||
@@ -74,21 +74,21 @@ internal class SubmissionEventsFetchingTask(
|
|||||||
return if (latestFetchedFinalization.get() != null) {
|
return if (latestFetchedFinalization.get() != null) {
|
||||||
log.trace(
|
log.trace(
|
||||||
"fetching submission events from L1 startBlockNumber={}",
|
"fetching submission events from L1 startBlockNumber={}",
|
||||||
latestFetchedFinalization.get().event.endBlockNumber + 1u
|
latestFetchedFinalization.get().event.endBlockNumber + 1u,
|
||||||
)
|
)
|
||||||
submissionEventsClient.findFinalizationAndDataSubmissionV3Events(
|
submissionEventsClient.findFinalizationAndDataSubmissionV3Events(
|
||||||
fromL1BlockNumber = latestFetchedFinalization.get().log.blockNumber.toBlockParameter(),
|
fromL1BlockNumber = latestFetchedFinalization.get().log.blockNumber.toBlockParameter(),
|
||||||
finalizationStartBlockNumber = latestFetchedFinalization.get().event.endBlockNumber + 1u
|
finalizationStartBlockNumber = latestFetchedFinalization.get().event.endBlockNumber + 1u,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
log.trace(
|
log.trace(
|
||||||
"fetching submission events from L1 startBlockNumber={}",
|
"fetching submission events from L1 startBlockNumber={}",
|
||||||
l2StartBlockNumber
|
l2StartBlockNumber,
|
||||||
)
|
)
|
||||||
submissionEventsClient
|
submissionEventsClient
|
||||||
.findFinalizationAndDataSubmissionV3EventsContainingL2BlockNumber(
|
.findFinalizationAndDataSubmissionV3EventsContainingL2BlockNumber(
|
||||||
fromL1BlockNumber = l1EarliestBlockWithFinalizationThatSupportRecovery,
|
fromL1BlockNumber = l1EarliestBlockWithFinalizationThatSupportRecovery,
|
||||||
l2BlockNumber = l2StartBlockNumber
|
l2BlockNumber = l2StartBlockNumber,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import kotlin.time.Duration.Companion.seconds
|
|||||||
*/
|
*/
|
||||||
data class SubmissionEventsAndData<T>(
|
data class SubmissionEventsAndData<T>(
|
||||||
val submissionEvents: FinalizationAndDataEventsV3,
|
val submissionEvents: FinalizationAndDataEventsV3,
|
||||||
val data: List<T>
|
val data: List<T>,
|
||||||
)
|
)
|
||||||
|
|
||||||
class SubmissionsFetchingTask(
|
class SubmissionsFetchingTask(
|
||||||
@@ -44,11 +44,11 @@ class SubmissionsFetchingTask(
|
|||||||
private val compressedBlobsQueueLimit: Int,
|
private val compressedBlobsQueueLimit: Int,
|
||||||
private val targetDecompressedBlobsQueueLimit: Int,
|
private val targetDecompressedBlobsQueueLimit: Int,
|
||||||
private val debugForceSyncStopBlockNumber: ULong?,
|
private val debugForceSyncStopBlockNumber: ULong?,
|
||||||
private val log: Logger = LogManager.getLogger(SubmissionsFetchingTask::class.java)
|
private val log: Logger = LogManager.getLogger(SubmissionsFetchingTask::class.java),
|
||||||
) : PeriodicPollingService(
|
) : PeriodicPollingService(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
pollingIntervalMs = l1PollingInterval.inWholeMilliseconds,
|
pollingIntervalMs = l1PollingInterval.inWholeMilliseconds,
|
||||||
log = log
|
log = log,
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
require(submissionEventsQueueLimit >= 1) {
|
require(submissionEventsQueueLimit >= 1) {
|
||||||
@@ -84,7 +84,7 @@ class SubmissionsFetchingTask(
|
|||||||
l2StartBlockNumber = l2StartBlockNumberToFetchInclusive,
|
l2StartBlockNumber = l2StartBlockNumberToFetchInclusive,
|
||||||
submissionEventsQueue = submissionEventsQueue,
|
submissionEventsQueue = submissionEventsQueue,
|
||||||
queueLimit = submissionEventsQueueLimit,
|
queueLimit = submissionEventsQueueLimit,
|
||||||
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber
|
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber,
|
||||||
)
|
)
|
||||||
private val blobFetchingTask = BlobsFetchingTask(
|
private val blobFetchingTask = BlobsFetchingTask(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
@@ -93,7 +93,7 @@ class SubmissionsFetchingTask(
|
|||||||
blobsFetcher = blobsFetcher,
|
blobsFetcher = blobsFetcher,
|
||||||
transactionDetailsClient = transactionDetailsClient,
|
transactionDetailsClient = transactionDetailsClient,
|
||||||
compressedBlobsQueue = compressedBlobsQueue,
|
compressedBlobsQueue = compressedBlobsQueue,
|
||||||
compressedBlobsQueueLimit = compressedBlobsQueueLimit
|
compressedBlobsQueueLimit = compressedBlobsQueueLimit,
|
||||||
)
|
)
|
||||||
private val blobDecompressionTask = BlobDecompressionTask(
|
private val blobDecompressionTask = BlobDecompressionTask(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
@@ -101,7 +101,7 @@ class SubmissionsFetchingTask(
|
|||||||
blobDecompressor = blobDecompressor,
|
blobDecompressor = blobDecompressor,
|
||||||
rawBlobsQueue = compressedBlobsQueue,
|
rawBlobsQueue = compressedBlobsQueue,
|
||||||
decompressedBlocksQueue = decompressedBlocksQueue,
|
decompressedBlocksQueue = decompressedBlocksQueue,
|
||||||
decompressedFinalizationQueueLimit = dynamicDecompressedBlobsQueueLimit::get
|
decompressedFinalizationQueueLimit = dynamicDecompressedBlobsQueueLimit::get,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
@@ -109,7 +109,7 @@ class SubmissionsFetchingTask(
|
|||||||
return SafeFuture.allOf(
|
return SafeFuture.allOf(
|
||||||
submissionEventsFetchingTask.start(),
|
submissionEventsFetchingTask.start(),
|
||||||
blobFetchingTask.start(),
|
blobFetchingTask.start(),
|
||||||
blobDecompressionTask.start()
|
blobDecompressionTask.start(),
|
||||||
).thenCompose { super.start() }
|
).thenCompose { super.start() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ class SubmissionsFetchingTask(
|
|||||||
return SafeFuture.allOf(
|
return SafeFuture.allOf(
|
||||||
submissionEventsFetchingTask.stop(),
|
submissionEventsFetchingTask.stop(),
|
||||||
blobFetchingTask.stop(),
|
blobFetchingTask.stop(),
|
||||||
blobDecompressionTask.stop()
|
blobDecompressionTask.stop(),
|
||||||
).thenCompose { super.stop() }
|
).thenCompose { super.stop() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ class SubmissionsFetchingTask(
|
|||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun pruneQueueForElementsUpToInclusive(
|
fun pruneQueueForElementsUpToInclusive(
|
||||||
elHeadBlockNumber: ULong
|
elHeadBlockNumber: ULong,
|
||||||
) {
|
) {
|
||||||
decompressedBlocksQueue.removeIf {
|
decompressedBlocksQueue.removeIf {
|
||||||
it.submissionEvents.dataFinalizedEvent.event.endBlockNumber <= elHeadBlockNumber
|
it.submissionEvents.dataFinalizedEvent.event.endBlockNumber <= elHeadBlockNumber
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class BlobDecompressorAndDeserializerV1Test {
|
|||||||
private val blockStaticFields = BlockHeaderStaticFields(
|
private val blockStaticFields = BlockHeaderStaticFields(
|
||||||
coinbase = Address.ZERO.toArray(),
|
coinbase = Address.ZERO.toArray(),
|
||||||
gasLimit = 30_000_000UL,
|
gasLimit = 30_000_000UL,
|
||||||
difficulty = 0UL
|
difficulty = 0UL,
|
||||||
)
|
)
|
||||||
private lateinit var decompressorToDomain: BlobDecompressorAndDeserializer
|
private lateinit var decompressorToDomain: BlobDecompressorAndDeserializer
|
||||||
private lateinit var vertx: Vertx
|
private lateinit var vertx: Vertx
|
||||||
@@ -39,7 +39,7 @@ class BlobDecompressorAndDeserializerV1Test {
|
|||||||
vertx = Vertx.vertx()
|
vertx = Vertx.vertx()
|
||||||
compressor = GoBackedBlobCompressor.getInstance(
|
compressor = GoBackedBlobCompressor.getInstance(
|
||||||
compressorVersion = BlobCompressorVersion.V1_2,
|
compressorVersion = BlobCompressorVersion.V1_2,
|
||||||
dataLimit = 124 * 1024
|
dataLimit = 124 * 1024,
|
||||||
)
|
)
|
||||||
val decompressor = GoNativeBlobDecompressorFactory.getInstance(BlobDecompressorVersion.V1_2_0)
|
val decompressor = GoNativeBlobDecompressorFactory.getInstance(BlobDecompressorVersion.V1_2_0)
|
||||||
decompressorToDomain = BlobDecompressorToDomainV1(decompressor, blockStaticFields, vertx)
|
decompressorToDomain = BlobDecompressorToDomainV1(decompressor, blockStaticFields, vertx)
|
||||||
@@ -57,7 +57,7 @@ class BlobDecompressorAndDeserializerV1Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun assertBlockCompressionAndDecompression(
|
private fun assertBlockCompressionAndDecompression(
|
||||||
blocksRLP: List<ByteArray>
|
blocksRLP: List<ByteArray>,
|
||||||
) {
|
) {
|
||||||
val blocks = blocksRLP.map(RLP::decodeBlockWithMainnetFunctions)
|
val blocks = blocksRLP.map(RLP::decodeBlockWithMainnetFunctions)
|
||||||
val startingBlockNumber = blocks[0].header.number.toULong()
|
val startingBlockNumber = blocks[0].header.number.toULong()
|
||||||
@@ -66,7 +66,7 @@ class BlobDecompressorAndDeserializerV1Test {
|
|||||||
|
|
||||||
val recoveredBlocks = decompressorToDomain.decompress(
|
val recoveredBlocks = decompressorToDomain.decompress(
|
||||||
startBlockNumber = startingBlockNumber,
|
startBlockNumber = startingBlockNumber,
|
||||||
blobs = blobs
|
blobs = blobs,
|
||||||
).get()
|
).get()
|
||||||
assertThat(recoveredBlocks[0].header.blockNumber).isEqualTo(startingBlockNumber)
|
assertThat(recoveredBlocks[0].header.blockNumber).isEqualTo(startingBlockNumber)
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ class BlobDecompressorAndDeserializerV1Test {
|
|||||||
|
|
||||||
private fun assertBlockData(
|
private fun assertBlockData(
|
||||||
uncompressed: BlockFromL1RecoveredData,
|
uncompressed: BlockFromL1RecoveredData,
|
||||||
original: Block
|
original: Block,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
assertThat(uncompressed.header.blockNumber).isEqualTo(original.header.number.toULong())
|
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} " +
|
"uncompressed block does not match expected original: blockNumber: ${e.message} " +
|
||||||
"\n original =$original " +
|
"\n original =$original " +
|
||||||
"\n uncompressed=$uncompressed ",
|
"\n uncompressed=$uncompressed ",
|
||||||
e
|
e,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assertTransactionData(
|
private fun assertTransactionData(
|
||||||
uncompressed: TransactionFromL1RecoveredData,
|
uncompressed: TransactionFromL1RecoveredData,
|
||||||
original: Transaction
|
original: Transaction,
|
||||||
) {
|
) {
|
||||||
assertThat(uncompressed.type).isEqualTo(original.type.serializedType.toUByte())
|
assertThat(uncompressed.type).isEqualTo(original.type.serializedType.toUByte())
|
||||||
assertThat(uncompressed.from).isEqualTo(original.sender.toArray())
|
assertThat(uncompressed.from).isEqualTo(original.sender.toArray())
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class StartingBlockCalculatorTest {
|
|||||||
lookbackFetchingIntervals(
|
lookbackFetchingIntervals(
|
||||||
headBlockNumber = 50UL,
|
headBlockNumber = 50UL,
|
||||||
recoveryStartBlockNumber = null,
|
recoveryStartBlockNumber = null,
|
||||||
lookbackWindow = 10UL
|
lookbackWindow = 10UL,
|
||||||
).also { intervals ->
|
).also { intervals ->
|
||||||
assertThat(intervals.l1Interval).isNull()
|
assertThat(intervals.l1Interval).isNull()
|
||||||
assertThat(intervals.elInterval).isEqualTo(BlockInterval(41UL, 50UL))
|
assertThat(intervals.elInterval).isEqualTo(BlockInterval(41UL, 50UL))
|
||||||
@@ -23,7 +23,7 @@ class StartingBlockCalculatorTest {
|
|||||||
lookbackFetchingIntervals(
|
lookbackFetchingIntervals(
|
||||||
headBlockNumber = 5UL,
|
headBlockNumber = 5UL,
|
||||||
recoveryStartBlockNumber = null,
|
recoveryStartBlockNumber = null,
|
||||||
lookbackWindow = 10UL
|
lookbackWindow = 10UL,
|
||||||
).also { intervals ->
|
).also { intervals ->
|
||||||
assertThat(intervals.l1Interval).isNull()
|
assertThat(intervals.l1Interval).isNull()
|
||||||
assertThat(intervals.elInterval).isEqualTo(BlockInterval(0UL, 5UL))
|
assertThat(intervals.elInterval).isEqualTo(BlockInterval(0UL, 5UL))
|
||||||
@@ -35,7 +35,7 @@ class StartingBlockCalculatorTest {
|
|||||||
lookbackFetchingIntervals(
|
lookbackFetchingIntervals(
|
||||||
headBlockNumber = 50UL,
|
headBlockNumber = 50UL,
|
||||||
recoveryStartBlockNumber = 51UL,
|
recoveryStartBlockNumber = 51UL,
|
||||||
lookbackWindow = 10UL
|
lookbackWindow = 10UL,
|
||||||
).also { intervals ->
|
).also { intervals ->
|
||||||
assertThat(intervals.l1Interval).isNull()
|
assertThat(intervals.l1Interval).isNull()
|
||||||
assertThat(intervals.elInterval).isEqualTo(BlockInterval(41UL, 50UL))
|
assertThat(intervals.elInterval).isEqualTo(BlockInterval(41UL, 50UL))
|
||||||
@@ -47,7 +47,7 @@ class StartingBlockCalculatorTest {
|
|||||||
lookbackFetchingIntervals(
|
lookbackFetchingIntervals(
|
||||||
headBlockNumber = 0UL,
|
headBlockNumber = 0UL,
|
||||||
recoveryStartBlockNumber = 1UL,
|
recoveryStartBlockNumber = 1UL,
|
||||||
lookbackWindow = 10UL
|
lookbackWindow = 10UL,
|
||||||
).also { intervals ->
|
).also { intervals ->
|
||||||
assertThat(intervals.l1Interval).isNull()
|
assertThat(intervals.l1Interval).isNull()
|
||||||
assertThat(intervals.elInterval).isEqualTo(BlockInterval(0UL, 0UL))
|
assertThat(intervals.elInterval).isEqualTo(BlockInterval(0UL, 0UL))
|
||||||
@@ -59,7 +59,7 @@ class StartingBlockCalculatorTest {
|
|||||||
lookbackFetchingIntervals(
|
lookbackFetchingIntervals(
|
||||||
headBlockNumber = 50UL,
|
headBlockNumber = 50UL,
|
||||||
recoveryStartBlockNumber = 10UL,
|
recoveryStartBlockNumber = 10UL,
|
||||||
lookbackWindow = 10UL
|
lookbackWindow = 10UL,
|
||||||
).also { intervals ->
|
).also { intervals ->
|
||||||
assertThat(intervals.l1Interval).isEqualTo(BlockInterval(41UL, 50UL))
|
assertThat(intervals.l1Interval).isEqualTo(BlockInterval(41UL, 50UL))
|
||||||
assertThat(intervals.elInterval).isNull()
|
assertThat(intervals.elInterval).isNull()
|
||||||
@@ -71,7 +71,7 @@ class StartingBlockCalculatorTest {
|
|||||||
lookbackFetchingIntervals(
|
lookbackFetchingIntervals(
|
||||||
headBlockNumber = 50UL,
|
headBlockNumber = 50UL,
|
||||||
recoveryStartBlockNumber = 45UL,
|
recoveryStartBlockNumber = 45UL,
|
||||||
lookbackWindow = 10UL
|
lookbackWindow = 10UL,
|
||||||
).also { intervals ->
|
).also { intervals ->
|
||||||
assertThat(intervals.l1Interval).isEqualTo(BlockInterval(45UL, 50UL))
|
assertThat(intervals.l1Interval).isEqualTo(BlockInterval(45UL, 50UL))
|
||||||
assertThat(intervals.elInterval).isEqualTo(BlockInterval(41UL, 44UL))
|
assertThat(intervals.elInterval).isEqualTo(BlockInterval(41UL, 44UL))
|
||||||
@@ -86,7 +86,7 @@ class StartingBlockCalculatorTest {
|
|||||||
startBlockToFetchFromL1(
|
startBlockToFetchFromL1(
|
||||||
headBlockNumber = 500UL,
|
headBlockNumber = 500UL,
|
||||||
recoveryStartBlockNumber = null,
|
recoveryStartBlockNumber = null,
|
||||||
lookbackWindow = 256UL
|
lookbackWindow = 256UL,
|
||||||
).also { result ->
|
).also { result ->
|
||||||
// Then
|
// Then
|
||||||
assertThat(result).isEqualTo(501UL)
|
assertThat(result).isEqualTo(501UL)
|
||||||
@@ -95,7 +95,7 @@ class StartingBlockCalculatorTest {
|
|||||||
startBlockToFetchFromL1(
|
startBlockToFetchFromL1(
|
||||||
headBlockNumber = 200UL,
|
headBlockNumber = 200UL,
|
||||||
recoveryStartBlockNumber = null,
|
recoveryStartBlockNumber = null,
|
||||||
lookbackWindow = 256UL
|
lookbackWindow = 256UL,
|
||||||
).also { result ->
|
).also { result ->
|
||||||
// Then
|
// Then
|
||||||
assertThat(result).isEqualTo(201UL)
|
assertThat(result).isEqualTo(201UL)
|
||||||
@@ -107,7 +107,7 @@ class StartingBlockCalculatorTest {
|
|||||||
startBlockToFetchFromL1(
|
startBlockToFetchFromL1(
|
||||||
headBlockNumber = 500UL,
|
headBlockNumber = 500UL,
|
||||||
recoveryStartBlockNumber = 250UL,
|
recoveryStartBlockNumber = 250UL,
|
||||||
lookbackWindow = 100UL
|
lookbackWindow = 100UL,
|
||||||
).also { result ->
|
).also { result ->
|
||||||
// Then
|
// Then
|
||||||
assertThat(result).isEqualTo(400UL)
|
assertThat(result).isEqualTo(400UL)
|
||||||
@@ -119,7 +119,7 @@ class StartingBlockCalculatorTest {
|
|||||||
startBlockToFetchFromL1(
|
startBlockToFetchFromL1(
|
||||||
headBlockNumber = 500UL,
|
headBlockNumber = 500UL,
|
||||||
recoveryStartBlockNumber = 450UL,
|
recoveryStartBlockNumber = 450UL,
|
||||||
lookbackWindow = 100UL
|
lookbackWindow = 100UL,
|
||||||
).also { result ->
|
).also { result ->
|
||||||
// Then
|
// Then
|
||||||
assertThat(result).isEqualTo(450UL)
|
assertThat(result).isEqualTo(450UL)
|
||||||
@@ -129,7 +129,7 @@ class StartingBlockCalculatorTest {
|
|||||||
startBlockToFetchFromL1(
|
startBlockToFetchFromL1(
|
||||||
headBlockNumber = 50UL,
|
headBlockNumber = 50UL,
|
||||||
recoveryStartBlockNumber = 45UL,
|
recoveryStartBlockNumber = 45UL,
|
||||||
lookbackWindow = 100UL
|
lookbackWindow = 100UL,
|
||||||
).also { result ->
|
).also { result ->
|
||||||
// Then
|
// Then
|
||||||
assertThat(result).isEqualTo(45UL)
|
assertThat(result).isEqualTo(45UL)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class ExecutionLayerInProcessClient(
|
|||||||
private val blockchainService: BlockchainService,
|
private val blockchainService: BlockchainService,
|
||||||
private val stateRecoveryModeManager: RecoveryModeManager,
|
private val stateRecoveryModeManager: RecoveryModeManager,
|
||||||
private val stateRecoveryStatusPersistence: RecoveryStatusPersistence,
|
private val stateRecoveryStatusPersistence: RecoveryStatusPersistence,
|
||||||
private val blockImporter: BlockImporter
|
private val blockImporter: BlockImporter,
|
||||||
) : ExecutionLayerClient {
|
) : ExecutionLayerClient {
|
||||||
companion object {
|
companion object {
|
||||||
fun create(
|
fun create(
|
||||||
@@ -29,7 +29,7 @@ class ExecutionLayerInProcessClient(
|
|||||||
simulatorService: BlockSimulationService,
|
simulatorService: BlockSimulationService,
|
||||||
synchronizationService: SynchronizationService,
|
synchronizationService: SynchronizationService,
|
||||||
stateRecoveryModeManager: RecoveryModeManager,
|
stateRecoveryModeManager: RecoveryModeManager,
|
||||||
stateRecoveryStatusPersistence: RecoveryStatusPersistence
|
stateRecoveryStatusPersistence: RecoveryStatusPersistence,
|
||||||
): ExecutionLayerInProcessClient {
|
): ExecutionLayerInProcessClient {
|
||||||
return ExecutionLayerInProcessClient(
|
return ExecutionLayerInProcessClient(
|
||||||
blockchainService = blockchainService,
|
blockchainService = blockchainService,
|
||||||
@@ -38,8 +38,8 @@ class ExecutionLayerInProcessClient(
|
|||||||
blockImporter = BlockImporter(
|
blockImporter = BlockImporter(
|
||||||
blockchainService = blockchainService,
|
blockchainService = blockchainService,
|
||||||
simulatorService = simulatorService,
|
simulatorService = simulatorService,
|
||||||
synchronizationService = synchronizationService
|
synchronizationService = synchronizationService,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,8 +71,8 @@ class ExecutionLayerInProcessClient(
|
|||||||
SafeFuture.completedFuture(
|
SafeFuture.completedFuture(
|
||||||
BlockNumberAndHash(
|
BlockNumberAndHash(
|
||||||
it.number.toULong(),
|
it.number.toULong(),
|
||||||
it.blockHash.toArray()
|
it.blockHash.toArray(),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
?: SafeFuture.failedFuture(IllegalArgumentException("Block not found for parameter: $blockParameter"))
|
?: SafeFuture.failedFuture(IllegalArgumentException("Block not found for parameter: $blockParameter"))
|
||||||
@@ -91,8 +91,8 @@ class ExecutionLayerInProcessClient(
|
|||||||
.completedFuture(
|
.completedFuture(
|
||||||
StateRecoveryStatus(
|
StateRecoveryStatus(
|
||||||
headBlockNumber = stateRecoveryModeManager.headBlockNumber,
|
headBlockNumber = stateRecoveryModeManager.headBlockNumber,
|
||||||
stateRecoverStartBlockNumber = stateRecoveryModeManager.targetBlockNumber
|
stateRecoverStartBlockNumber = stateRecoveryModeManager.targetBlockNumber,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,8 +102,8 @@ class ExecutionLayerInProcessClient(
|
|||||||
return SafeFuture.completedFuture(
|
return SafeFuture.completedFuture(
|
||||||
StateRecoveryStatus(
|
StateRecoveryStatus(
|
||||||
headBlockNumber = stateRecoveryModeManager.headBlockNumber,
|
headBlockNumber = stateRecoveryModeManager.headBlockNumber,
|
||||||
stateRecoverStartBlockNumber = stateRecoveryStatusPersistence.getRecoveryStartBlockNumber()
|
stateRecoverStartBlockNumber = stateRecoveryStatusPersistence.getRecoveryStartBlockNumber(),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ class ExecutionLayerInProcessClient(
|
|||||||
} else {
|
} else {
|
||||||
log.debug(
|
log.debug(
|
||||||
"importing blocks from blob: blocks={}",
|
"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),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ fun createAppAllInProcess(
|
|||||||
blobScanRequestRetryConfig: RetryConfig,
|
blobScanRequestRetryConfig: RetryConfig,
|
||||||
blobscanRequestRatelimitBackoffDelay: Duration?,
|
blobscanRequestRatelimitBackoffDelay: Duration?,
|
||||||
blockHeaderStaticFields: BlockHeaderStaticFields,
|
blockHeaderStaticFields: BlockHeaderStaticFields,
|
||||||
appConfig: StateRecoveryApp.Config
|
appConfig: StateRecoveryApp.Config,
|
||||||
): StateRecoveryApp {
|
): StateRecoveryApp {
|
||||||
return createAppClients(
|
return createAppClients(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
@@ -49,7 +49,7 @@ fun createAppAllInProcess(
|
|||||||
l1RequestRetryConfig = l1RequestRetryConfig,
|
l1RequestRetryConfig = l1RequestRetryConfig,
|
||||||
blobScanEndpoint = blobScanEndpoint,
|
blobScanEndpoint = blobScanEndpoint,
|
||||||
blobScanRequestRetryConfig = blobScanRequestRetryConfig,
|
blobScanRequestRetryConfig = blobScanRequestRetryConfig,
|
||||||
blobscanRequestRateLimitBackoffDelay = blobscanRequestRatelimitBackoffDelay
|
blobscanRequestRateLimitBackoffDelay = blobscanRequestRatelimitBackoffDelay,
|
||||||
).let { clients ->
|
).let { clients ->
|
||||||
val app = StateRecoveryApp(
|
val app = StateRecoveryApp(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
@@ -60,7 +60,7 @@ fun createAppAllInProcess(
|
|||||||
stateManagerClient = clients.stateManagerClient,
|
stateManagerClient = clients.stateManagerClient,
|
||||||
transactionDetailsClient = clients.transactionDetailsClient,
|
transactionDetailsClient = clients.transactionDetailsClient,
|
||||||
blockHeaderStaticFields = blockHeaderStaticFields,
|
blockHeaderStaticFields = blockHeaderStaticFields,
|
||||||
config = appConfig
|
config = appConfig,
|
||||||
)
|
)
|
||||||
app
|
app
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ data class AppClients(
|
|||||||
val ethLogsSearcher: EthLogsSearcherImpl,
|
val ethLogsSearcher: EthLogsSearcherImpl,
|
||||||
val blobScanClient: BlobScanClient,
|
val blobScanClient: BlobScanClient,
|
||||||
val stateManagerClient: StateManagerClientV1,
|
val stateManagerClient: StateManagerClientV1,
|
||||||
val transactionDetailsClient: TransactionDetailsClient
|
val transactionDetailsClient: TransactionDetailsClient,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun RetryConfig.toRequestRetryConfig(): RequestRetryConfig {
|
fun RetryConfig.toRequestRetryConfig(): RequestRetryConfig {
|
||||||
@@ -79,7 +79,7 @@ fun RetryConfig.toRequestRetryConfig(): RequestRetryConfig {
|
|||||||
maxRetries = this.maxRetries,
|
maxRetries = this.maxRetries,
|
||||||
timeout = this.timeout,
|
timeout = this.timeout,
|
||||||
backoffDelay = this.backoffDelay,
|
backoffDelay = this.backoffDelay,
|
||||||
failuresWarningThreshold = this.failuresWarningThreshold
|
failuresWarningThreshold = this.failuresWarningThreshold,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,14 +95,14 @@ fun createAppClients(
|
|||||||
stateManagerClientEndpoint: URI,
|
stateManagerClientEndpoint: URI,
|
||||||
blobscanRequestRateLimitBackoffDelay: Duration? = null,
|
blobscanRequestRateLimitBackoffDelay: Duration? = null,
|
||||||
stateManagerRequestRetry: RetryConfig = RetryConfig(backoffDelay = 1.seconds),
|
stateManagerRequestRetry: RetryConfig = RetryConfig(backoffDelay = 1.seconds),
|
||||||
zkStateManagerVersion: String = "2.3.0"
|
zkStateManagerVersion: String = "2.3.0",
|
||||||
): AppClients {
|
): AppClients {
|
||||||
val lineaContractClient = Web3JLineaRollupSmartContractClientReadOnly(
|
val lineaContractClient = Web3JLineaRollupSmartContractClientReadOnly(
|
||||||
contractAddress = smartContractAddress,
|
contractAddress = smartContractAddress,
|
||||||
web3j = createWeb3jHttpClient(
|
web3j = createWeb3jHttpClient(
|
||||||
rpcUrl = l1RpcEndpoint.toString(),
|
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 ethLogsSearcher = run {
|
||||||
val log = LogManager.getLogger("linea.plugin.staterecovery.clients.l1.logs-searcher")
|
val log = LogManager.getLogger("linea.plugin.staterecovery.clients.l1.logs-searcher")
|
||||||
@@ -110,15 +110,15 @@ fun createAppClients(
|
|||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
rpcUrl = l1RpcEndpoint.toString(),
|
rpcUrl = l1RpcEndpoint.toString(),
|
||||||
requestRetryConfig = l1RequestRetryConfig,
|
requestRetryConfig = l1RequestRetryConfig,
|
||||||
log = log
|
log = log,
|
||||||
)
|
)
|
||||||
EthLogsSearcherImpl(
|
EthLogsSearcherImpl(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
ethApiClient = web3jEthApiClient,
|
ethApiClient = web3jEthApiClient,
|
||||||
config = EthLogsSearcherImpl.Config(
|
config = EthLogsSearcherImpl.Config(
|
||||||
loopSuccessBackoffDelay = l1SuccessBackoffDelay
|
loopSuccessBackoffDelay = l1SuccessBackoffDelay,
|
||||||
),
|
),
|
||||||
log = log
|
log = log,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val blobScanClient = BlobScanClient.create(
|
val blobScanClient = BlobScanClient.create(
|
||||||
@@ -126,7 +126,7 @@ fun createAppClients(
|
|||||||
endpoint = blobScanEndpoint,
|
endpoint = blobScanEndpoint,
|
||||||
requestRetryConfig = blobScanRequestRetryConfig,
|
requestRetryConfig = blobScanRequestRetryConfig,
|
||||||
logger = LogManager.getLogger("linea.plugin.staterecovery.clients.l1.blob-scan"),
|
logger = LogManager.getLogger("linea.plugin.staterecovery.clients.l1.blob-scan"),
|
||||||
rateLimitBackoffDelay = blobscanRequestRateLimitBackoffDelay
|
rateLimitBackoffDelay = blobscanRequestRateLimitBackoffDelay,
|
||||||
)
|
)
|
||||||
val jsonRpcClientFactory = VertxHttpJsonRpcClientFactory(vertx, MicrometerMetricsFacade(meterRegistry))
|
val jsonRpcClientFactory = VertxHttpJsonRpcClientFactory(vertx, MicrometerMetricsFacade(meterRegistry))
|
||||||
val stateManagerClient: StateManagerClientV1 = StateManagerV1JsonRpcClient.create(
|
val stateManagerClient: StateManagerClientV1 = StateManagerV1JsonRpcClient.create(
|
||||||
@@ -135,19 +135,19 @@ fun createAppClients(
|
|||||||
maxInflightRequestsPerClient = 10u,
|
maxInflightRequestsPerClient = 10u,
|
||||||
requestRetry = stateManagerRequestRetry.toRequestRetryConfig(),
|
requestRetry = stateManagerRequestRetry.toRequestRetryConfig(),
|
||||||
zkStateManagerVersion = zkStateManagerVersion,
|
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(
|
val transactionDetailsClient: TransactionDetailsClient = VertxTransactionDetailsClient.create(
|
||||||
jsonRpcClientFactory = jsonRpcClientFactory,
|
jsonRpcClientFactory = jsonRpcClientFactory,
|
||||||
endpoint = l1RpcEndpoint,
|
endpoint = l1RpcEndpoint,
|
||||||
retryConfig = l1RequestRetryConfig.toRequestRetryConfig(),
|
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(
|
return AppClients(
|
||||||
lineaContractClient = lineaContractClient,
|
lineaContractClient = lineaContractClient,
|
||||||
ethLogsSearcher = ethLogsSearcher,
|
ethLogsSearcher = ethLogsSearcher,
|
||||||
blobScanClient = blobScanClient,
|
blobScanClient = blobScanClient,
|
||||||
stateManagerClient = stateManagerClient,
|
stateManagerClient = stateManagerClient,
|
||||||
transactionDetailsClient = transactionDetailsClient
|
transactionDetailsClient = transactionDetailsClient,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import org.hyperledger.besu.plugin.data.BlockHeader
|
|||||||
|
|
||||||
data class BlockContextData(
|
data class BlockContextData(
|
||||||
private val blockHeader: BlockHeader,
|
private val blockHeader: BlockHeader,
|
||||||
private val blockBody: BlockBody
|
private val blockBody: BlockBody,
|
||||||
) : BlockContext {
|
) : BlockContext {
|
||||||
override fun getBlockHeader(): BlockHeader = blockHeader
|
override fun getBlockHeader(): BlockHeader = blockHeader
|
||||||
override fun getBlockBody(): BlockBody = blockBody
|
override fun getBlockBody(): BlockBody = blockBody
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import java.util.concurrent.ConcurrentHashMap
|
|||||||
|
|
||||||
class BlockHashLookupWithRecoverySupport(
|
class BlockHashLookupWithRecoverySupport(
|
||||||
val lookbackWindow: ULong,
|
val lookbackWindow: ULong,
|
||||||
private val log: Logger = LogManager.getLogger(BlockHashLookupWithRecoverySupport::class.java)
|
private val log: Logger = LogManager.getLogger(BlockHashLookupWithRecoverySupport::class.java),
|
||||||
) : BlockHashLookup {
|
) : BlockHashLookup {
|
||||||
private val lookbackHashesMap = ConcurrentHashMap<ULong, ByteArray>()
|
private val lookbackHashesMap = ConcurrentHashMap<ULong, ByteArray>()
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ class BlockImporter(
|
|||||||
private val simulatorService: BlockSimulationService,
|
private val simulatorService: BlockSimulationService,
|
||||||
private val synchronizationService: SynchronizationService,
|
private val synchronizationService: SynchronizationService,
|
||||||
private val blockHashLookup: BlockHashLookupWithRecoverySupport = BlockHashLookupWithRecoverySupport(
|
private val blockHashLookup: BlockHashLookupWithRecoverySupport = BlockHashLookupWithRecoverySupport(
|
||||||
lookbackWindow = 256UL
|
lookbackWindow = 256UL,
|
||||||
)
|
),
|
||||||
) {
|
) {
|
||||||
private val log = LogManager.getLogger(BlockImporter::class.java)
|
private val log = LogManager.getLogger(BlockImporter::class.java)
|
||||||
private val chainId = blockchainService.chainId.orElseThrow().toULong()
|
private val chainId = blockchainService.chainId.orElseThrow().toULong()
|
||||||
@@ -40,16 +40,16 @@ class BlockImporter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun executeBlockWithTransactionsWithoutSignature(
|
private fun executeBlockWithTransactionsWithoutSignature(
|
||||||
block: BlockFromL1RecoveredData
|
block: BlockFromL1RecoveredData,
|
||||||
): PluginBlockSimulationResult {
|
): PluginBlockSimulationResult {
|
||||||
log.trace(
|
log.trace(
|
||||||
"simulating import block={} blockHash={}",
|
"simulating import block={} blockHash={}",
|
||||||
block.header.blockNumber,
|
block.header.blockNumber,
|
||||||
block.header.blockHash.encodeHex()
|
block.header.blockHash.encodeHex(),
|
||||||
)
|
)
|
||||||
val transactions = TransactionMapper.mapToBesu(
|
val transactions = TransactionMapper.mapToBesu(
|
||||||
block.transactions,
|
block.transactions,
|
||||||
chainId
|
chainId,
|
||||||
)
|
)
|
||||||
val parentBlockNumber = block.header.blockNumber.toLong() - 1
|
val parentBlockNumber = block.header.blockNumber.toLong() - 1
|
||||||
|
|
||||||
@@ -58,13 +58,13 @@ class BlockImporter(
|
|||||||
parentBlockNumber,
|
parentBlockNumber,
|
||||||
transactions,
|
transactions,
|
||||||
createOverrides(block, blockHashLookup::getHash),
|
createOverrides(block, blockHashLookup::getHash),
|
||||||
StateOverrideMap()
|
StateOverrideMap(),
|
||||||
)
|
)
|
||||||
|
|
||||||
log.trace(
|
log.trace(
|
||||||
" import simulation result: block={} blockHeader={}",
|
" import simulation result: block={} blockHeader={}",
|
||||||
executedBlockResult.blockHeader.number,
|
executedBlockResult.blockHeader.number,
|
||||||
executedBlockResult.blockHeader
|
executedBlockResult.blockHeader,
|
||||||
)
|
)
|
||||||
return executedBlockResult
|
return executedBlockResult
|
||||||
}
|
}
|
||||||
@@ -73,7 +73,7 @@ class BlockImporter(
|
|||||||
log.trace(
|
log.trace(
|
||||||
"calling simulateAndPersistWorldState block={} blockHeader={}",
|
"calling simulateAndPersistWorldState block={} blockHeader={}",
|
||||||
context.blockHeader.number,
|
context.blockHeader.number,
|
||||||
context.blockHeader
|
context.blockHeader,
|
||||||
)
|
)
|
||||||
val parentBlockNumber = context.blockHeader.number - 1
|
val parentBlockNumber = context.blockHeader.number - 1
|
||||||
val importedBlockResult =
|
val importedBlockResult =
|
||||||
@@ -81,12 +81,12 @@ class BlockImporter(
|
|||||||
parentBlockNumber,
|
parentBlockNumber,
|
||||||
context.blockBody.transactions,
|
context.blockBody.transactions,
|
||||||
createOverrides(context.blockHeader, blockHashLookup::getHash),
|
createOverrides(context.blockHeader, blockHashLookup::getHash),
|
||||||
StateOverrideMap()
|
StateOverrideMap(),
|
||||||
)
|
)
|
||||||
log.trace(
|
log.trace(
|
||||||
"simulateAndPersistWorldState result: block={} blockHeader={}",
|
"simulateAndPersistWorldState result: block={} blockHeader={}",
|
||||||
context.blockHeader.number,
|
context.blockHeader.number,
|
||||||
importedBlockResult.blockHeader
|
importedBlockResult.blockHeader,
|
||||||
)
|
)
|
||||||
storeAndSetHead(importedBlockResult)
|
storeAndSetHead(importedBlockResult)
|
||||||
return importedBlockResult
|
return importedBlockResult
|
||||||
@@ -95,12 +95,12 @@ class BlockImporter(
|
|||||||
private fun storeAndSetHead(block: PluginBlockSimulationResult) {
|
private fun storeAndSetHead(block: PluginBlockSimulationResult) {
|
||||||
log.debug(
|
log.debug(
|
||||||
"storeAndSetHead result: blockHeader={}",
|
"storeAndSetHead result: blockHeader={}",
|
||||||
block.blockHeader
|
block.blockHeader,
|
||||||
)
|
)
|
||||||
blockchainService.storeBlock(
|
blockchainService.storeBlock(
|
||||||
block.blockHeader,
|
block.blockHeader,
|
||||||
block.blockBody,
|
block.blockBody,
|
||||||
block.receipts
|
block.receipts,
|
||||||
)
|
)
|
||||||
synchronizationService.setHeadUnsafe(block.blockHeader, block.blockBody)
|
synchronizationService.setHeadUnsafe(block.blockHeader, block.blockBody)
|
||||||
}
|
}
|
||||||
@@ -108,7 +108,7 @@ class BlockImporter(
|
|||||||
companion object {
|
companion object {
|
||||||
fun createOverrides(
|
fun createOverrides(
|
||||||
blockFromBlob: BlockFromL1RecoveredData,
|
blockFromBlob: BlockFromL1RecoveredData,
|
||||||
blockHashLookup: (Long) -> Hash
|
blockHashLookup: (Long) -> Hash,
|
||||||
): BlockOverrides {
|
): BlockOverrides {
|
||||||
return BlockOverrides.builder()
|
return BlockOverrides.builder()
|
||||||
.blockHash(Hash.wrap(Bytes32.wrap(blockFromBlob.header.blockHash)))
|
.blockHash(Hash.wrap(Bytes32.wrap(blockFromBlob.header.blockHash)))
|
||||||
@@ -124,7 +124,7 @@ class BlockImporter(
|
|||||||
|
|
||||||
fun createOverrides(
|
fun createOverrides(
|
||||||
blockHeader: BlockHeader,
|
blockHeader: BlockHeader,
|
||||||
blockHashLookup: (Long) -> Hash
|
blockHashLookup: (Long) -> Hash,
|
||||||
): BlockOverrides {
|
): BlockOverrides {
|
||||||
return BlockOverrides.builder()
|
return BlockOverrides.builder()
|
||||||
.feeRecipient(blockHeader.coinbase)
|
.feeRecipient(blockHeader.coinbase)
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ open class LineaStateRecoveryPlugin : BesuPlugin {
|
|||||||
warningExceptionTime = 5.minutes,
|
warningExceptionTime = 5.minutes,
|
||||||
jvmMetricsEnabled = false,
|
jvmMetricsEnabled = false,
|
||||||
prometheusMetricsEnabled = false,
|
prometheusMetricsEnabled = false,
|
||||||
preferNativeTransport = false
|
preferNativeTransport = false,
|
||||||
)
|
)
|
||||||
private val cliOptions = PluginCliOptions()
|
private val cliOptions = PluginCliOptions()
|
||||||
private lateinit var serviceManager: ServiceManager
|
private lateinit var serviceManager: ServiceManager
|
||||||
@@ -59,18 +59,18 @@ open class LineaStateRecoveryPlugin : BesuPlugin {
|
|||||||
val blockHeaderStaticFields = BlockHeaderStaticFields(
|
val blockHeaderStaticFields = BlockHeaderStaticFields(
|
||||||
coinbase = config.lineaSequencerBeneficiaryAddress.toArray(),
|
coinbase = config.lineaSequencerBeneficiaryAddress.toArray(),
|
||||||
gasLimit = config.lineaBlockGasLimit,
|
gasLimit = config.lineaBlockGasLimit,
|
||||||
difficulty = config.lineaBlockDifficulty
|
difficulty = config.lineaBlockDifficulty,
|
||||||
)
|
)
|
||||||
this.recoveryStatusPersistence = FileBasedRecoveryStatusPersistence(
|
this.recoveryStatusPersistence = FileBasedRecoveryStatusPersistence(
|
||||||
serviceManager.getServiceOrThrow(BesuConfiguration::class.java)
|
serviceManager.getServiceOrThrow(BesuConfiguration::class.java)
|
||||||
.dataPath
|
.dataPath
|
||||||
.resolve("plugin-staterecovery-status.json")
|
.resolve("plugin-staterecovery-status.json"),
|
||||||
)
|
)
|
||||||
log.info(
|
log.info(
|
||||||
"starting: config={} blockHeaderStaticFields={} previousRecoveryStartBlockNumber={}",
|
"starting: config={} blockHeaderStaticFields={} previousRecoveryStartBlockNumber={}",
|
||||||
config,
|
config,
|
||||||
blockHeaderStaticFields,
|
blockHeaderStaticFields,
|
||||||
this.recoveryStatusPersistence.getRecoveryStartBlockNumber()
|
this.recoveryStatusPersistence.getRecoveryStartBlockNumber(),
|
||||||
)
|
)
|
||||||
|
|
||||||
val synchronizationService = serviceManager.getServiceOrThrow(SynchronizationService::class.java)
|
val synchronizationService = serviceManager.getServiceOrThrow(SynchronizationService::class.java)
|
||||||
@@ -80,7 +80,7 @@ open class LineaStateRecoveryPlugin : BesuPlugin {
|
|||||||
recoveryStatePersistence = this.recoveryStatusPersistence,
|
recoveryStatePersistence = this.recoveryStatusPersistence,
|
||||||
synchronizationService = synchronizationService,
|
synchronizationService = synchronizationService,
|
||||||
headBlockNumber = blockchainService.chainHeadHeader.number.toULong(),
|
headBlockNumber = blockchainService.chainHeadHeader.number.toULong(),
|
||||||
debugForceSyncStopBlockNumber = config.debugForceSyncStopBlockNumber
|
debugForceSyncStopBlockNumber = config.debugForceSyncStopBlockNumber,
|
||||||
)
|
)
|
||||||
val simulatorService = serviceManager.getServiceOrThrow(BlockSimulationService::class.java)
|
val simulatorService = serviceManager.getServiceOrThrow(BlockSimulationService::class.java)
|
||||||
val executionLayerClient = ExecutionLayerInProcessClient.create(
|
val executionLayerClient = ExecutionLayerInProcessClient.create(
|
||||||
@@ -88,7 +88,7 @@ open class LineaStateRecoveryPlugin : BesuPlugin {
|
|||||||
stateRecoveryModeManager = this.recoveryModeManager,
|
stateRecoveryModeManager = this.recoveryModeManager,
|
||||||
stateRecoveryStatusPersistence = this.recoveryStatusPersistence,
|
stateRecoveryStatusPersistence = this.recoveryStatusPersistence,
|
||||||
simulatorService = simulatorService,
|
simulatorService = simulatorService,
|
||||||
synchronizationService = synchronizationService
|
synchronizationService = synchronizationService,
|
||||||
)
|
)
|
||||||
|
|
||||||
this.stateRecoverApp = run {
|
this.stateRecoverApp = run {
|
||||||
@@ -112,8 +112,8 @@ open class LineaStateRecoveryPlugin : BesuPlugin {
|
|||||||
l1LatestSearchBlock = config.l1HighestSearchBlock,
|
l1LatestSearchBlock = config.l1HighestSearchBlock,
|
||||||
l1PollingInterval = config.l1PollingInterval,
|
l1PollingInterval = config.l1PollingInterval,
|
||||||
overridingRecoveryStartBlockNumber = config.overridingRecoveryStartBlockNumber,
|
overridingRecoveryStartBlockNumber = config.overridingRecoveryStartBlockNumber,
|
||||||
debugForceSyncStopBlockNumber = config.debugForceSyncStopBlockNumber
|
debugForceSyncStopBlockNumber = config.debugForceSyncStopBlockNumber,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// add recoverty mode manager as listener to block added events
|
// add recoverty mode manager as listener to block added events
|
||||||
@@ -129,7 +129,7 @@ open class LineaStateRecoveryPlugin : BesuPlugin {
|
|||||||
this.recoveryModeManager.enableRecoveryModeIfNecessary()
|
this.recoveryModeManager.enableRecoveryModeIfNecessary()
|
||||||
log.info(
|
log.info(
|
||||||
"started: recoveryStartBlockNumber={}",
|
"started: recoveryStartBlockNumber={}",
|
||||||
this.recoveryStatusPersistence.getRecoveryStartBlockNumber()
|
this.recoveryStatusPersistence.getRecoveryStartBlockNumber(),
|
||||||
)
|
)
|
||||||
this.stateRecoverApp.start().get()
|
this.stateRecoverApp.start().get()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ data class PluginConfig(
|
|||||||
val blobscanRequestRatelimitBackoffDelay: kotlin.time.Duration?,
|
val blobscanRequestRatelimitBackoffDelay: kotlin.time.Duration?,
|
||||||
val shomeiEndpoint: URI,
|
val shomeiEndpoint: URI,
|
||||||
val overridingRecoveryStartBlockNumber: ULong? = null,
|
val overridingRecoveryStartBlockNumber: ULong? = null,
|
||||||
val debugForceSyncStopBlockNumber: ULong? = null
|
val debugForceSyncStopBlockNumber: ULong? = null,
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
require(l1PollingInterval >= 1.milliseconds) { "Polling interval=$l1PollingInterval must be greater than 1ms." }
|
require(l1PollingInterval >= 1.milliseconds) { "Polling interval=$l1PollingInterval must be greater than 1ms." }
|
||||||
@@ -43,7 +43,7 @@ class PluginCliOptions {
|
|||||||
description = ["Linea sequencer beneficiary address"],
|
description = ["Linea sequencer beneficiary address"],
|
||||||
required = true,
|
required = true,
|
||||||
converter = [AddressConverter::class],
|
converter = [AddressConverter::class],
|
||||||
defaultValue = "\${env:LINEA_SEQUENCER_BENEFICIARY_ADDRESS}"
|
defaultValue = "\${env:LINEA_SEQUENCER_BENEFICIARY_ADDRESS}",
|
||||||
)
|
)
|
||||||
lateinit var lineaSequencerBeneficiaryAddress: Address
|
lateinit var lineaSequencerBeneficiaryAddress: Address
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ class PluginCliOptions {
|
|||||||
names = ["--$cliOptionsPrefix-linea-block-gas-limit"],
|
names = ["--$cliOptionsPrefix-linea-block-gas-limit"],
|
||||||
description = ["Linea Block gas limit. Default 2B (2_000_000_000)"],
|
description = ["Linea Block gas limit. Default 2B (2_000_000_000)"],
|
||||||
required = false,
|
required = false,
|
||||||
defaultValue = "\${env:LINEA_BLOCK_GAS_LIMIT}"
|
defaultValue = "\${env:LINEA_BLOCK_GAS_LIMIT}",
|
||||||
)
|
)
|
||||||
var lineaBlockGasLimit: Long = 2_000_000_000L
|
var lineaBlockGasLimit: Long = 2_000_000_000L
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ class PluginCliOptions {
|
|||||||
names = ["--$cliOptionsPrefix-linea-block-difficulty"],
|
names = ["--$cliOptionsPrefix-linea-block-difficulty"],
|
||||||
description = ["Linea Block difficulty. Default 2"],
|
description = ["Linea Block difficulty. Default 2"],
|
||||||
required = false,
|
required = false,
|
||||||
defaultValue = "\${env:LINEA_BLOCK_DIFFICULTY}"
|
defaultValue = "\${env:LINEA_BLOCK_DIFFICULTY}",
|
||||||
)
|
)
|
||||||
var lineaBlockDifficulty: Long = 2
|
var lineaBlockDifficulty: Long = 2
|
||||||
|
|
||||||
@@ -68,14 +68,14 @@ class PluginCliOptions {
|
|||||||
description = ["L1 smart contract address"],
|
description = ["L1 smart contract address"],
|
||||||
required = true,
|
required = true,
|
||||||
converter = [AddressConverter::class],
|
converter = [AddressConverter::class],
|
||||||
defaultValue = "\${env:L1_ROLLUP_CONTRACT_ADDRESS}"
|
defaultValue = "\${env:L1_ROLLUP_CONTRACT_ADDRESS}",
|
||||||
)
|
)
|
||||||
lateinit var l1SmartContractAddress: Address
|
lateinit var l1SmartContractAddress: Address
|
||||||
|
|
||||||
@CommandLine.Option(
|
@CommandLine.Option(
|
||||||
names = ["--$cliOptionsPrefix-l1-endpoint"],
|
names = ["--$cliOptionsPrefix-l1-endpoint"],
|
||||||
description = ["L1 RPC endpoint"],
|
description = ["L1 RPC endpoint"],
|
||||||
required = true
|
required = true,
|
||||||
)
|
)
|
||||||
lateinit var l1RpcEndpoint: URI
|
lateinit var l1RpcEndpoint: URI
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ class PluginCliOptions {
|
|||||||
names = ["--$cliOptionsPrefix-l1-polling-interval"],
|
names = ["--$cliOptionsPrefix-l1-polling-interval"],
|
||||||
defaultValue = "PT12S",
|
defaultValue = "PT12S",
|
||||||
description = ["L1 polling interval for new finalized blobs"],
|
description = ["L1 polling interval for new finalized blobs"],
|
||||||
required = false
|
required = false,
|
||||||
)
|
)
|
||||||
var l1PollingInterval: java.time.Duration = java.time.Duration.ofSeconds(12)
|
var l1PollingInterval: java.time.Duration = java.time.Duration.ofSeconds(12)
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ class PluginCliOptions {
|
|||||||
names = ["--$cliOptionsPrefix-l1-get-logs-chunk-size"],
|
names = ["--$cliOptionsPrefix-l1-get-logs-chunk-size"],
|
||||||
defaultValue = "10000",
|
defaultValue = "10000",
|
||||||
description = ["Chuck size (fromBlock..toBlock) for eth_getLogs initial search loop"],
|
description = ["Chuck size (fromBlock..toBlock) for eth_getLogs initial search loop"],
|
||||||
required = false
|
required = false,
|
||||||
)
|
)
|
||||||
var l1GetLogsChunkSize: Int = 10_000
|
var l1GetLogsChunkSize: Int = 10_000
|
||||||
|
|
||||||
@@ -100,10 +100,10 @@ class PluginCliOptions {
|
|||||||
defaultValue = "EARLIEST",
|
defaultValue = "EARLIEST",
|
||||||
description = [
|
description = [
|
||||||
"Earliest L1 Block to search for new finalizations on startup.",
|
"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],
|
converter = [BlockParameterConverter::class],
|
||||||
required = false
|
required = false,
|
||||||
)
|
)
|
||||||
var l1EarliestSearchBlock: BlockParameter = BlockParameter.Tag.EARLIEST
|
var l1EarliestSearchBlock: BlockParameter = BlockParameter.Tag.EARLIEST
|
||||||
|
|
||||||
@@ -112,10 +112,10 @@ class PluginCliOptions {
|
|||||||
defaultValue = "FINALIZED",
|
defaultValue = "FINALIZED",
|
||||||
description = [
|
description = [
|
||||||
"Highest L1 Block to search for new finalizations.",
|
"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],
|
converter = [BlockParameterConverter::class],
|
||||||
required = false
|
required = false,
|
||||||
)
|
)
|
||||||
var l1HighestSearchBlock: BlockParameter = BlockParameter.Tag.FINALIZED
|
var l1HighestSearchBlock: BlockParameter = BlockParameter.Tag.FINALIZED
|
||||||
|
|
||||||
@@ -123,9 +123,9 @@ class PluginCliOptions {
|
|||||||
names = ["--$cliOptionsPrefix-l1-success-backoff-delay"],
|
names = ["--$cliOptionsPrefix-l1-success-backoff-delay"],
|
||||||
description = [
|
description = [
|
||||||
"L1 RPC api retry backoff delay, default none. ",
|
"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
|
var l1RequestSuccessBackoffDelay: java.time.Duration? = null
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ class PluginCliOptions {
|
|||||||
names = ["--$cliOptionsPrefix-l1-retry-backoff-delay"],
|
names = ["--$cliOptionsPrefix-l1-retry-backoff-delay"],
|
||||||
defaultValue = "PT1S",
|
defaultValue = "PT1S",
|
||||||
description = ["L1 RPC api retry backoff delay, default 1s"],
|
description = ["L1 RPC api retry backoff delay, default 1s"],
|
||||||
required = false
|
required = false,
|
||||||
)
|
)
|
||||||
var l1RequestRetryBackoffDelay: java.time.Duration = java.time.Duration.ofSeconds(1)
|
var l1RequestRetryBackoffDelay: java.time.Duration = java.time.Duration.ofSeconds(1)
|
||||||
|
|
||||||
@@ -141,9 +141,9 @@ class PluginCliOptions {
|
|||||||
names = ["--$cliOptionsPrefix-l1-retry-timeout"],
|
names = ["--$cliOptionsPrefix-l1-retry-timeout"],
|
||||||
description = [
|
description = [
|
||||||
"L1 RPC api stop retrying as soon as timeout has elapsed or limit is reached",
|
"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
|
var l1RequestRetryTimeout: java.time.Duration? = null
|
||||||
|
|
||||||
@@ -151,37 +151,37 @@ class PluginCliOptions {
|
|||||||
names = ["--$cliOptionsPrefix-l1-retry-limit"],
|
names = ["--$cliOptionsPrefix-l1-retry-limit"],
|
||||||
description = [
|
description = [
|
||||||
"L1 RPC api stop retrying when limit is reached or timeout has elapsed",
|
"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
|
var l1RequestRetryLimit: Int? = null
|
||||||
|
|
||||||
@CommandLine.Option(
|
@CommandLine.Option(
|
||||||
names = ["--$cliOptionsPrefix-shomei-endpoint"],
|
names = ["--$cliOptionsPrefix-shomei-endpoint"],
|
||||||
description = ["shomei (state manager) endpoint"],
|
description = ["shomei (state manager) endpoint"],
|
||||||
required = true
|
required = true,
|
||||||
)
|
)
|
||||||
lateinit var shomeiEndpoint: URI
|
lateinit var shomeiEndpoint: URI
|
||||||
|
|
||||||
@CommandLine.Option(
|
@CommandLine.Option(
|
||||||
names = ["--$cliOptionsPrefix-blobscan-endpoint"],
|
names = ["--$cliOptionsPrefix-blobscan-endpoint"],
|
||||||
description = ["blobscan api endpoint"],
|
description = ["blobscan api endpoint"],
|
||||||
required = true
|
required = true,
|
||||||
)
|
)
|
||||||
lateinit var blobscanEndpoint: URI
|
lateinit var blobscanEndpoint: URI
|
||||||
|
|
||||||
@CommandLine.Option(
|
@CommandLine.Option(
|
||||||
names = ["--$cliOptionsPrefix-blobscan-retry-backoff-delay"],
|
names = ["--$cliOptionsPrefix-blobscan-retry-backoff-delay"],
|
||||||
description = ["blobscan api retry backoff delay, default 1s"],
|
description = ["blobscan api retry backoff delay, default 1s"],
|
||||||
required = false
|
required = false,
|
||||||
)
|
)
|
||||||
var blobscanRequestRetryBackoffDelay: java.time.Duration = java.time.Duration.ofSeconds(1)
|
var blobscanRequestRetryBackoffDelay: java.time.Duration = java.time.Duration.ofSeconds(1)
|
||||||
|
|
||||||
@CommandLine.Option(
|
@CommandLine.Option(
|
||||||
names = ["--$cliOptionsPrefix-blobscan-ratelimit-backoff-delay"],
|
names = ["--$cliOptionsPrefix-blobscan-ratelimit-backoff-delay"],
|
||||||
description = ["blobscan api retry ratelimit backoff delay, default is disabled"],
|
description = ["blobscan api retry ratelimit backoff delay, default is disabled"],
|
||||||
required = false
|
required = false,
|
||||||
)
|
)
|
||||||
var blobscanRequestRatelimitBackoffDelay: java.time.Duration? = null
|
var blobscanRequestRatelimitBackoffDelay: java.time.Duration? = null
|
||||||
|
|
||||||
@@ -189,9 +189,9 @@ class PluginCliOptions {
|
|||||||
names = ["--$cliOptionsPrefix-blobscan-retry-timeout"],
|
names = ["--$cliOptionsPrefix-blobscan-retry-timeout"],
|
||||||
description = [
|
description = [
|
||||||
"Blobscan api stop retrying as soon as timeout has elapsed or limit is reached.",
|
"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
|
var blobscanRequestRetryTimeout: java.time.Duration? = null
|
||||||
|
|
||||||
@@ -199,9 +199,9 @@ class PluginCliOptions {
|
|||||||
names = ["--$cliOptionsPrefix-blobscan-retry-limit"],
|
names = ["--$cliOptionsPrefix-blobscan-retry-limit"],
|
||||||
description = [
|
description = [
|
||||||
"Blobscan api stop retrying when limit is reached or timeout has elapsed",
|
"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
|
var blobscanRequestRetryLimit: Int? = null
|
||||||
|
|
||||||
@@ -209,10 +209,10 @@ class PluginCliOptions {
|
|||||||
names = ["--$cliOptionsPrefix-overriding-recovery-start-block-number"],
|
names = ["--$cliOptionsPrefix-overriding-recovery-start-block-number"],
|
||||||
description = [
|
description = [
|
||||||
"Tries to force the recovery start block number to the given value. " +
|
"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}",
|
defaultValue = "\${env:STATERECOVERY_OVERRIDE_START_BLOCK_NUMBER}",
|
||||||
required = false
|
required = false,
|
||||||
)
|
)
|
||||||
var overridingRecoveryStartBlockNumber: Long? = null
|
var overridingRecoveryStartBlockNumber: Long? = null
|
||||||
|
|
||||||
@@ -220,10 +220,10 @@ class PluginCliOptions {
|
|||||||
names = ["--$cliOptionsPrefix-debug-force-sync-stop-block-number"],
|
names = ["--$cliOptionsPrefix-debug-force-sync-stop-block-number"],
|
||||||
description = [
|
description = [
|
||||||
"Forces Besu to stop syncing at the given block number. " +
|
"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}",
|
defaultValue = "\${env:STATERECOVERY_DEBUG_FORCE_STOP_SYNC_BLOCK_NUMBER}",
|
||||||
required = false
|
required = false,
|
||||||
)
|
)
|
||||||
var debugForceSyncStopBlockNumber: Long? = null
|
var debugForceSyncStopBlockNumber: Long? = null
|
||||||
|
|
||||||
@@ -252,25 +252,25 @@ class PluginCliOptions {
|
|||||||
l1RequestRetryConfig = RetryConfig(
|
l1RequestRetryConfig = RetryConfig(
|
||||||
backoffDelay = l1RequestRetryBackoffDelay.toKotlinDuration(),
|
backoffDelay = l1RequestRetryBackoffDelay.toKotlinDuration(),
|
||||||
timeout = l1RequestRetryTimeout?.toKotlinDuration(),
|
timeout = l1RequestRetryTimeout?.toKotlinDuration(),
|
||||||
maxRetries = l1RequestRetryLimit?.toUInt()
|
maxRetries = l1RequestRetryLimit?.toUInt(),
|
||||||
),
|
),
|
||||||
blobscanEndpoint = blobscanEndpoint,
|
blobscanEndpoint = blobscanEndpoint,
|
||||||
blobScanRequestRetryConfig = RetryConfig(
|
blobScanRequestRetryConfig = RetryConfig(
|
||||||
backoffDelay = blobscanRequestRetryBackoffDelay.toKotlinDuration(),
|
backoffDelay = blobscanRequestRetryBackoffDelay.toKotlinDuration(),
|
||||||
timeout = blobscanRequestRetryTimeout?.toKotlinDuration(),
|
timeout = blobscanRequestRetryTimeout?.toKotlinDuration(),
|
||||||
maxRetries = blobscanRequestRetryLimit?.toUInt()
|
maxRetries = blobscanRequestRetryLimit?.toUInt(),
|
||||||
),
|
),
|
||||||
blobscanRequestRatelimitBackoffDelay = blobscanRequestRatelimitBackoffDelay?.toKotlinDuration(),
|
blobscanRequestRatelimitBackoffDelay = blobscanRequestRatelimitBackoffDelay?.toKotlinDuration(),
|
||||||
shomeiEndpoint = shomeiEndpoint,
|
shomeiEndpoint = shomeiEndpoint,
|
||||||
overridingRecoveryStartBlockNumber = overridingRecoveryStartBlockNumber?.toULong(),
|
overridingRecoveryStartBlockNumber = overridingRecoveryStartBlockNumber?.toULong(),
|
||||||
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber?.toULong()
|
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber?.toULong(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
class AddressConverter : CommandLine.ITypeConverter<Address> {
|
class AddressConverter : CommandLine.ITypeConverter<Address> {
|
||||||
override fun convert(value: String): Address {
|
override fun convert(value: String): Address {
|
||||||
return Address.fromHexStringStrict(value) ?: throw CommandLine.TypeConversionException(
|
return Address.fromHexStringStrict(value) ?: throw CommandLine.TypeConversionException(
|
||||||
"Invalid address: $value"
|
"Invalid address: $value",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class RecoveryModeManager(
|
|||||||
private val miningService: MiningService,
|
private val miningService: MiningService,
|
||||||
private val recoveryStatePersistence: RecoveryStatusPersistence,
|
private val recoveryStatePersistence: RecoveryStatusPersistence,
|
||||||
private val debugForceSyncStopBlockNumber: ULong? = null,
|
private val debugForceSyncStopBlockNumber: ULong? = null,
|
||||||
headBlockNumber: ULong
|
headBlockNumber: ULong,
|
||||||
) :
|
) :
|
||||||
BesuEvents.BlockAddedListener {
|
BesuEvents.BlockAddedListener {
|
||||||
private val log: Logger = LogManager.getLogger(RecoveryModeManager::class.java.name)
|
private val log: Logger = LogManager.getLogger(RecoveryModeManager::class.java.name)
|
||||||
@@ -37,7 +37,7 @@ class RecoveryModeManager(
|
|||||||
log.info(
|
log.info(
|
||||||
"enabling recovery mode immediately at blockNumber={} recoveryTargetBlockNumber={}",
|
"enabling recovery mode immediately at blockNumber={} recoveryTargetBlockNumber={}",
|
||||||
headBlockNumber,
|
headBlockNumber,
|
||||||
targetBlockNumber
|
targetBlockNumber,
|
||||||
)
|
)
|
||||||
switchToRecoveryMode()
|
switchToRecoveryMode()
|
||||||
}
|
}
|
||||||
@@ -56,14 +56,14 @@ class RecoveryModeManager(
|
|||||||
log.info(
|
log.info(
|
||||||
"Stopping synchronization services at block={} recoveryTargetBlockNumber={} was reached",
|
"Stopping synchronization services at block={} recoveryTargetBlockNumber={} was reached",
|
||||||
headBlockNumber,
|
headBlockNumber,
|
||||||
targetBlockNumber
|
targetBlockNumber,
|
||||||
)
|
)
|
||||||
switchToRecoveryMode()
|
switchToRecoveryMode()
|
||||||
} else if (debugForceSyncStopBlockNumber != null && headBlockNumber >= debugForceSyncStopBlockNumber) {
|
} else if (debugForceSyncStopBlockNumber != null && headBlockNumber >= debugForceSyncStopBlockNumber) {
|
||||||
log.info(
|
log.info(
|
||||||
"Stopping synchronization services at block={} debugForceSyncStopBlockNumber={}",
|
"Stopping synchronization services at block={} debugForceSyncStopBlockNumber={}",
|
||||||
headBlockNumber,
|
headBlockNumber,
|
||||||
debugForceSyncStopBlockNumber
|
debugForceSyncStopBlockNumber,
|
||||||
)
|
)
|
||||||
stopBesuServices()
|
stopBesuServices()
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ class RecoveryModeManager(
|
|||||||
|
|
||||||
private fun hasReachedTargetBlock(
|
private fun hasReachedTargetBlock(
|
||||||
headBlockNumber: ULong = this.headBlockNumber,
|
headBlockNumber: ULong = this.headBlockNumber,
|
||||||
targetBlockNumber: ULong? = this.targetBlockNumber
|
targetBlockNumber: ULong? = this.targetBlockNumber,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return (headBlockNumber + 1u) >= (targetBlockNumber ?: ULong.MAX_VALUE)
|
return (headBlockNumber + 1u) >= (targetBlockNumber ?: ULong.MAX_VALUE)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ object TransactionMapper {
|
|||||||
*/
|
*/
|
||||||
fun mapToBesu(
|
fun mapToBesu(
|
||||||
transaction: TransactionFromL1RecoveredData,
|
transaction: TransactionFromL1RecoveredData,
|
||||||
chainId: ULong
|
chainId: ULong,
|
||||||
): Transaction {
|
): Transaction {
|
||||||
val builder = Transaction.builder()
|
val builder = Transaction.builder()
|
||||||
builder
|
builder
|
||||||
@@ -48,13 +48,13 @@ object TransactionMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun mapAccessListEntries(
|
private fun mapAccessListEntries(
|
||||||
accessList: List<AccessTuple>?
|
accessList: List<AccessTuple>?,
|
||||||
): List<AccessListEntry>? {
|
): List<AccessListEntry>? {
|
||||||
return accessList
|
return accessList
|
||||||
?.map { accessTupleParameter ->
|
?.map { accessTupleParameter ->
|
||||||
AccessListEntry.createAccessListEntry(
|
AccessListEntry.createAccessListEntry(
|
||||||
accessTupleParameter.address.toBesuAddress(),
|
accessTupleParameter.address.toBesuAddress(),
|
||||||
accessTupleParameter.storageKeys.map { it.encodeHex() }
|
accessTupleParameter.storageKeys.map { it.encodeHex() },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@ object TransactionMapper {
|
|||||||
*/
|
*/
|
||||||
fun mapToBesu(
|
fun mapToBesu(
|
||||||
transactions: List<TransactionFromL1RecoveredData>,
|
transactions: List<TransactionFromL1RecoveredData>,
|
||||||
defaultChainId: ULong
|
defaultChainId: ULong,
|
||||||
): List<Transaction> {
|
): List<Transaction> {
|
||||||
return transactions.map { tx -> mapToBesu(tx, defaultChainId) }
|
return transactions.map { tx -> mapToBesu(tx, defaultChainId) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,16 +15,16 @@ class BlockHashLookupWithRecoverySupportTest {
|
|||||||
lookback.addLookbackHashes(
|
lookback.addLookbackHashes(
|
||||||
mapOf(
|
mapOf(
|
||||||
1UL to hashOf(1UL),
|
1UL to hashOf(1UL),
|
||||||
2UL to hashOf(3UL)
|
2UL to hashOf(3UL),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
assertThatThrownBy {
|
assertThatThrownBy {
|
||||||
lookback.addLookbackHashes(
|
lookback.addLookbackHashes(
|
||||||
mapOf(
|
mapOf(
|
||||||
1UL to hashOf(1UL),
|
1UL to hashOf(1UL),
|
||||||
3UL to hashOf(3UL)
|
3UL to hashOf(3UL),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.isInstanceOf(IllegalArgumentException::class.java)
|
.isInstanceOf(IllegalArgumentException::class.java)
|
||||||
@@ -34,7 +34,7 @@ class BlockHashLookupWithRecoverySupportTest {
|
|||||||
@Test
|
@Test
|
||||||
fun `addHeadBlockHash should update and prune the lookback hashes outside the lookback window`() {
|
fun `addHeadBlockHash should update and prune the lookback hashes outside the lookback window`() {
|
||||||
val lookback = BlockHashLookupWithRecoverySupport(
|
val lookback = BlockHashLookupWithRecoverySupport(
|
||||||
lookbackWindow = 3UL
|
lookbackWindow = 3UL,
|
||||||
)
|
)
|
||||||
|
|
||||||
lookback.addHeadBlockHash(0UL, hashOf(123UL))
|
lookback.addHeadBlockHash(0UL, hashOf(123UL))
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ class StaticVertxHttpRequestRateLimiter(
|
|||||||
.div(5)
|
.div(5)
|
||||||
.coerceAtLeast(1.milliseconds),
|
.coerceAtLeast(1.milliseconds),
|
||||||
private val requestLogFormatter: VertxHttpLoggingFormatter,
|
private val requestLogFormatter: VertxHttpLoggingFormatter,
|
||||||
private val logger: Logger = LogManager.getLogger(StaticVertxHttpRequestRateLimiter::class.java)
|
private val logger: Logger = LogManager.getLogger(StaticVertxHttpRequestRateLimiter::class.java),
|
||||||
) : VertxHttpRequestSender {
|
) : VertxHttpRequestSender {
|
||||||
private data class RequestAndFutureResponse(
|
private data class RequestAndFutureResponse(
|
||||||
val request: HttpRequest<Buffer>,
|
val request: HttpRequest<Buffer>,
|
||||||
val future: SafeFuture<HttpResponse<Buffer>>
|
val future: SafeFuture<HttpResponse<Buffer>>,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val rateLimitPerSecond = 1.seconds.div(rateLimitBackoffDelay).toInt()
|
private val rateLimitPerSecond = 1.seconds.div(rateLimitBackoffDelay).toInt()
|
||||||
@@ -54,7 +54,7 @@ class StaticVertxHttpRequestRateLimiter(
|
|||||||
rateLimitPerSecond,
|
rateLimitPerSecond,
|
||||||
requestQueue.size,
|
requestQueue.size,
|
||||||
rateLimitBackoffDelay - elapsedTimeSinceLastRequest,
|
rateLimitBackoffDelay - elapsedTimeSinceLastRequest,
|
||||||
requestLogFormatter.toLogString(requestQueue.peek().request)
|
requestLogFormatter.toLogString(requestQueue.peek().request),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ class StaticVertxHttpRequestRateLimiter(
|
|||||||
rateLimitPerSecond,
|
rateLimitPerSecond,
|
||||||
requestQueue.size,
|
requestQueue.size,
|
||||||
rateLimitBackoffDelay - lastRequestFiredTime.elapsedNow(),
|
rateLimitBackoffDelay - lastRequestFiredTime.elapsedNow(),
|
||||||
requestLogFormatter.toLogString(request)
|
requestLogFormatter.toLogString(request),
|
||||||
)
|
)
|
||||||
|
|
||||||
requestQueue.add(req)
|
requestQueue.add(req)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ interface VertxHttpLoggingFormatter {
|
|||||||
fun toLogString(
|
fun toLogString(
|
||||||
request: HttpRequest<Buffer>,
|
request: HttpRequest<Buffer>,
|
||||||
response: HttpResponse<Buffer>? = null,
|
response: HttpResponse<Buffer>? = null,
|
||||||
failureCause: Throwable? = null
|
failureCause: Throwable? = null,
|
||||||
): String
|
): String
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,14 +22,14 @@ fun HttpRequest<*>.fullUri(): String {
|
|||||||
scheme,
|
scheme,
|
||||||
this.host(),
|
this.host(),
|
||||||
this.port(),
|
this.port(),
|
||||||
path
|
path,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
class VertxRestLoggingFormatter(
|
class VertxRestLoggingFormatter(
|
||||||
private val includeFullUri: Boolean = false,
|
private val includeFullUri: Boolean = false,
|
||||||
private val uriTransformer: (String) -> String = { it },
|
private val uriTransformer: (String) -> String = { it },
|
||||||
private val responseLogMaxSize: UInt? = null
|
private val responseLogMaxSize: UInt? = null,
|
||||||
) : VertxHttpLoggingFormatter {
|
) : VertxHttpLoggingFormatter {
|
||||||
fun HttpRequest<*>.uriToLog(): String {
|
fun HttpRequest<*>.uriToLog(): String {
|
||||||
return if (includeFullUri) {
|
return if (includeFullUri) {
|
||||||
@@ -46,14 +46,14 @@ class VertxRestLoggingFormatter(
|
|||||||
override fun toLogString(
|
override fun toLogString(
|
||||||
request: HttpRequest<Buffer>,
|
request: HttpRequest<Buffer>,
|
||||||
response: HttpResponse<Buffer>?,
|
response: HttpResponse<Buffer>?,
|
||||||
failureCause: Throwable?
|
failureCause: Throwable?,
|
||||||
): String {
|
): String {
|
||||||
return if (failureCause != null) {
|
return if (failureCause != null) {
|
||||||
String.format(
|
String.format(
|
||||||
"<-- %s %s %s",
|
"<-- %s %s %s",
|
||||||
request.method(),
|
request.method(),
|
||||||
uriTransformer.invoke(request.uriToLog()),
|
uriTransformer.invoke(request.uriToLog()),
|
||||||
failureCause.message?.let { errorMsg -> "error=$errorMsg" } ?: ""
|
failureCause.message?.let { errorMsg -> "error=$errorMsg" } ?: "",
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
val responseToLog = response?.bodyAsString()?.let { bodyStr ->
|
val responseToLog = response?.bodyAsString()?.let { bodyStr ->
|
||||||
@@ -68,7 +68,7 @@ class VertxRestLoggingFormatter(
|
|||||||
request.method(),
|
request.method(),
|
||||||
uriTransformer.invoke(request.uriToLog()),
|
uriTransformer.invoke(request.uriToLog()),
|
||||||
response?.statusCode() ?: "",
|
response?.statusCode() ?: "",
|
||||||
responseToLog
|
responseToLog,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ interface VertxHttpRequestSender {
|
|||||||
* Handy to avoid creating anonymous classes.
|
* Handy to avoid creating anonymous classes.
|
||||||
*/
|
*/
|
||||||
class SimpleVertxHttpRequestSender(
|
class SimpleVertxHttpRequestSender(
|
||||||
private val requestLogger: VertxRequestLogger
|
private val requestLogger: VertxRequestLogger,
|
||||||
) : VertxHttpRequestSender {
|
) : VertxHttpRequestSender {
|
||||||
override fun makeRequest(request: HttpRequest<Buffer>): SafeFuture<HttpResponse<Buffer>> {
|
override fun makeRequest(request: HttpRequest<Buffer>): SafeFuture<HttpResponse<Buffer>> {
|
||||||
requestLogger.logRequest(request)
|
requestLogger.logRequest(request)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ object VertxHttpRequestSenderFactory {
|
|||||||
rateLimitBackoffDelay: Duration? = null,
|
rateLimitBackoffDelay: Duration? = null,
|
||||||
retryableErrorCodes: Set<Int> = setOf(429, 503, 504),
|
retryableErrorCodes: Set<Int> = setOf(429, 503, 504),
|
||||||
logFormatter: VertxHttpLoggingFormatter,
|
logFormatter: VertxHttpLoggingFormatter,
|
||||||
baseRequestSender: VertxHttpRequestSender
|
baseRequestSender: VertxHttpRequestSender,
|
||||||
): VertxHttpRequestSender {
|
): VertxHttpRequestSender {
|
||||||
val rateLimitedSender = rateLimitBackoffDelay
|
val rateLimitedSender = rateLimitBackoffDelay
|
||||||
?.let {
|
?.let {
|
||||||
@@ -21,7 +21,7 @@ object VertxHttpRequestSenderFactory {
|
|||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
requestSender = baseRequestSender,
|
requestSender = baseRequestSender,
|
||||||
rateLimitBackoffDelay = rateLimitBackoffDelay,
|
rateLimitBackoffDelay = rateLimitBackoffDelay,
|
||||||
requestLogFormatter = logFormatter
|
requestLogFormatter = logFormatter,
|
||||||
)
|
)
|
||||||
} ?: baseRequestSender
|
} ?: baseRequestSender
|
||||||
val sender = requestRetryConfig
|
val sender = requestRetryConfig
|
||||||
@@ -30,7 +30,7 @@ object VertxHttpRequestSenderFactory {
|
|||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
requestSender = rateLimitedSender,
|
requestSender = rateLimitedSender,
|
||||||
requestRetryConfig = requestRetryConfig,
|
requestRetryConfig = requestRetryConfig,
|
||||||
retryableErrorCodes = retryableErrorCodes
|
retryableErrorCodes = retryableErrorCodes,
|
||||||
)
|
)
|
||||||
} ?: rateLimitedSender
|
} ?: rateLimitedSender
|
||||||
|
|
||||||
@@ -45,13 +45,13 @@ object VertxHttpRequestSenderFactory {
|
|||||||
requestResponseLogLevel: Level = Level.TRACE,
|
requestResponseLogLevel: Level = Level.TRACE,
|
||||||
failuresLogLevel: Level = Level.DEBUG,
|
failuresLogLevel: Level = Level.DEBUG,
|
||||||
retryableErrorCodes: Set<Int> = setOf(429, 503, 504),
|
retryableErrorCodes: Set<Int> = setOf(429, 503, 504),
|
||||||
logFormatter: VertxHttpLoggingFormatter
|
logFormatter: VertxHttpLoggingFormatter,
|
||||||
): VertxHttpRequestSender {
|
): VertxHttpRequestSender {
|
||||||
val requestLogger = VertxRestRequestLogger(
|
val requestLogger = VertxRestRequestLogger(
|
||||||
log = logger,
|
log = logger,
|
||||||
requestResponseLogLevel = requestResponseLogLevel,
|
requestResponseLogLevel = requestResponseLogLevel,
|
||||||
failuresLogLevel = failuresLogLevel,
|
failuresLogLevel = failuresLogLevel,
|
||||||
logFormatter = logFormatter
|
logFormatter = logFormatter,
|
||||||
)
|
)
|
||||||
return createWithBaseSender(
|
return createWithBaseSender(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
@@ -59,7 +59,7 @@ object VertxHttpRequestSenderFactory {
|
|||||||
rateLimitBackoffDelay = rateLimitBackoffDelay,
|
rateLimitBackoffDelay = rateLimitBackoffDelay,
|
||||||
retryableErrorCodes = retryableErrorCodes,
|
retryableErrorCodes = retryableErrorCodes,
|
||||||
logFormatter = logFormatter,
|
logFormatter = logFormatter,
|
||||||
baseRequestSender = SimpleVertxHttpRequestSender(requestLogger)
|
baseRequestSender = SimpleVertxHttpRequestSender(requestLogger),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ interface VertxRequestLogger {
|
|||||||
fun logResponse(
|
fun logResponse(
|
||||||
request: HttpRequest<Buffer>,
|
request: HttpRequest<Buffer>,
|
||||||
response: HttpResponse<Buffer>? = null,
|
response: HttpResponse<Buffer>? = null,
|
||||||
failureCause: Throwable? = null
|
failureCause: Throwable? = null,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -19,18 +19,18 @@ class VertxRestRequestLogger(
|
|||||||
private val log: Logger,
|
private val log: Logger,
|
||||||
private val logFormatter: VertxHttpLoggingFormatter,
|
private val logFormatter: VertxHttpLoggingFormatter,
|
||||||
private val requestResponseLogLevel: Level = Level.TRACE,
|
private val requestResponseLogLevel: Level = Level.TRACE,
|
||||||
private val failuresLogLevel: Level = Level.DEBUG
|
private val failuresLogLevel: Level = Level.DEBUG,
|
||||||
) : VertxRequestLogger {
|
) : VertxRequestLogger {
|
||||||
constructor(
|
constructor(
|
||||||
log: Logger,
|
log: Logger,
|
||||||
responseLogMaxSize: UInt? = null,
|
responseLogMaxSize: UInt? = null,
|
||||||
requestResponseLogLevel: Level = Level.TRACE,
|
requestResponseLogLevel: Level = Level.TRACE,
|
||||||
failuresLogLevel: Level = Level.DEBUG
|
failuresLogLevel: Level = Level.DEBUG,
|
||||||
) : this(
|
) : this(
|
||||||
log = log,
|
log = log,
|
||||||
logFormatter = VertxRestLoggingFormatter(responseLogMaxSize = responseLogMaxSize),
|
logFormatter = VertxRestLoggingFormatter(responseLogMaxSize = responseLogMaxSize),
|
||||||
requestResponseLogLevel = requestResponseLogLevel,
|
requestResponseLogLevel = requestResponseLogLevel,
|
||||||
failuresLogLevel = failuresLogLevel
|
failuresLogLevel = failuresLogLevel,
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun logRequest(request: HttpRequest<Buffer>, logLevel: Level = requestResponseLogLevel) {
|
private fun logRequest(request: HttpRequest<Buffer>, logLevel: Level = requestResponseLogLevel) {
|
||||||
@@ -46,7 +46,7 @@ class VertxRestRequestLogger(
|
|||||||
override fun logResponse(
|
override fun logResponse(
|
||||||
request: HttpRequest<Buffer>,
|
request: HttpRequest<Buffer>,
|
||||||
response: HttpResponse<Buffer>?,
|
response: HttpResponse<Buffer>?,
|
||||||
failureCause: Throwable?
|
failureCause: Throwable?,
|
||||||
) {
|
) {
|
||||||
val isError = response?.statusCode()?.let(::isNotSuccessStatusCode) ?: true
|
val isError = response?.statusCode()?.let(::isNotSuccessStatusCode) ?: true
|
||||||
val logLevel = if (isError) failuresLogLevel else requestResponseLogLevel
|
val logLevel = if (isError) failuresLogLevel else requestResponseLogLevel
|
||||||
|
|||||||
@@ -17,15 +17,15 @@ class VertxRequestRetrier(
|
|||||||
backoffDelay = requestRetryConfig.backoffDelay,
|
backoffDelay = requestRetryConfig.backoffDelay,
|
||||||
maxRetries = requestRetryConfig.maxRetries?.toInt(),
|
maxRetries = requestRetryConfig.maxRetries?.toInt(),
|
||||||
timeout = requestRetryConfig.timeout,
|
timeout = requestRetryConfig.timeout,
|
||||||
vertx = vertx
|
vertx = vertx,
|
||||||
)
|
),
|
||||||
) : VertxHttpRequestSender {
|
) : VertxHttpRequestSender {
|
||||||
override fun makeRequest(request: HttpRequest<Buffer>): SafeFuture<HttpResponse<Buffer>> {
|
override fun makeRequest(request: HttpRequest<Buffer>): SafeFuture<HttpResponse<Buffer>> {
|
||||||
return asyncRetryer
|
return asyncRetryer
|
||||||
.retry(
|
.retry(
|
||||||
stopRetriesPredicate = { response: HttpResponse<Buffer> ->
|
stopRetriesPredicate = { response: HttpResponse<Buffer> ->
|
||||||
response.statusCode() !in retryableErrorCodes
|
response.statusCode() !in retryableErrorCodes
|
||||||
}
|
},
|
||||||
) {
|
) {
|
||||||
requestSender.makeRequest(request)
|
requestSender.makeRequest(request)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import kotlin.time.Duration
|
|||||||
|
|
||||||
class BlobScanClient(
|
class BlobScanClient(
|
||||||
private val restClient: RestClient<JsonObject>,
|
private val restClient: RestClient<JsonObject>,
|
||||||
private val log: Logger = LogManager.getLogger(BlobScanClient::class.java)
|
private val log: Logger = LogManager.getLogger(BlobScanClient::class.java),
|
||||||
) : BlobFetcher {
|
) : BlobFetcher {
|
||||||
fun getBlobById(id: String): SafeFuture<ByteArray> {
|
fun getBlobById(id: String): SafeFuture<ByteArray> {
|
||||||
return restClient
|
return restClient
|
||||||
@@ -31,7 +31,7 @@ class BlobScanClient(
|
|||||||
} else {
|
} else {
|
||||||
throw RuntimeException(
|
throw RuntimeException(
|
||||||
"error fetching blobId=$id " +
|
"error fetching blobId=$id " +
|
||||||
"errorMessage=${response.body?.getString("message") ?: ""}"
|
"errorMessage=${response.body?.getString("message") ?: ""}",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ class BlobScanClient(
|
|||||||
requestRetryConfig: RetryConfig,
|
requestRetryConfig: RetryConfig,
|
||||||
rateLimitBackoffDelay: Duration? = null,
|
rateLimitBackoffDelay: Duration? = null,
|
||||||
logger: Logger = LogManager.getLogger(BlobScanClient::class.java),
|
logger: Logger = LogManager.getLogger(BlobScanClient::class.java),
|
||||||
responseLogMaxSize: UInt? = 1000u
|
responseLogMaxSize: UInt? = 1000u,
|
||||||
): BlobScanClient {
|
): BlobScanClient {
|
||||||
val logFormatter = VertxRestLoggingFormatter(responseLogMaxSize = responseLogMaxSize)
|
val logFormatter = VertxRestLoggingFormatter(responseLogMaxSize = responseLogMaxSize)
|
||||||
|
|
||||||
@@ -61,16 +61,16 @@ class BlobScanClient(
|
|||||||
logger = logger,
|
logger = logger,
|
||||||
requestResponseLogLevel = Level.DEBUG,
|
requestResponseLogLevel = Level.DEBUG,
|
||||||
failuresLogLevel = Level.DEBUG,
|
failuresLogLevel = Level.DEBUG,
|
||||||
logFormatter = logFormatter
|
logFormatter = logFormatter,
|
||||||
)
|
)
|
||||||
val restClient = VertxRestClient(
|
val restClient = VertxRestClient(
|
||||||
webClient = WebClient.create(vertx, WebClientOptions().setDefaultsFrom(endpoint)),
|
webClient = WebClient.create(vertx, WebClientOptions().setDefaultsFrom(endpoint)),
|
||||||
responseParser = { it.toJsonObject() },
|
responseParser = { it.toJsonObject() },
|
||||||
requestSender = requestSender
|
requestSender = requestSender,
|
||||||
)
|
)
|
||||||
return BlobScanClient(
|
return BlobScanClient(
|
||||||
restClient = restClient,
|
restClient = restClient,
|
||||||
log = logger
|
log = logger,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import tech.pegasys.teku.infrastructure.async.SafeFuture
|
|||||||
// TODO: move to a common module
|
// TODO: move to a common module
|
||||||
data class RestResponse<T>(
|
data class RestResponse<T>(
|
||||||
val statusCode: Int,
|
val statusCode: Int,
|
||||||
val body: T?
|
val body: T?,
|
||||||
)
|
)
|
||||||
|
|
||||||
interface RestClient<Response> {
|
interface RestClient<Response> {
|
||||||
@@ -20,13 +20,13 @@ class VertxRestClient<Response>(
|
|||||||
private val webClient: WebClient,
|
private val webClient: WebClient,
|
||||||
private val responseParser: (Buffer) -> Response,
|
private val responseParser: (Buffer) -> Response,
|
||||||
private val requestSender: VertxHttpRequestSender,
|
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> {
|
) : RestClient<Response> {
|
||||||
override fun get(path: String): SafeFuture<RestResponse<Response>> {
|
override fun get(path: String): SafeFuture<RestResponse<Response>> {
|
||||||
return requestSender.makeRequest(
|
return requestSender.makeRequest(
|
||||||
webClient
|
webClient
|
||||||
.get(path)
|
.get(path)
|
||||||
.apply { requestHeaders.forEach(::putHeader) }
|
.apply { requestHeaders.forEach(::putHeader) },
|
||||||
)
|
)
|
||||||
.thenApply { response ->
|
.thenApply { response ->
|
||||||
val parsedResponse = response.body()?.let(responseParser)
|
val parsedResponse = response.body()?.let(responseParser)
|
||||||
|
|||||||
@@ -16,17 +16,25 @@ import kotlin.time.TimeSource
|
|||||||
fun httpResponse(
|
fun httpResponse(
|
||||||
statusCode: Int = 200,
|
statusCode: Int = 200,
|
||||||
statusMessage: String = "OK",
|
statusMessage: String = "OK",
|
||||||
body: Buffer = Buffer.buffer()
|
body: Buffer = Buffer.buffer(),
|
||||||
): HttpResponse<Buffer> {
|
): HttpResponse<Buffer> {
|
||||||
return HttpResponseImpl(
|
return HttpResponseImpl(
|
||||||
/* version = */ HttpVersion.HTTP_1_1,
|
/* version = */
|
||||||
/* statusCode = */ statusCode,
|
HttpVersion.HTTP_1_1,
|
||||||
/* statusMessage = */ statusMessage,
|
/* statusCode = */
|
||||||
/* headers = */ HeadersMultiMap(),
|
statusCode,
|
||||||
/* trailers = */ HeadersMultiMap(),
|
/* statusMessage = */
|
||||||
/* cookies = */ emptyList<String>(),
|
statusMessage,
|
||||||
/* body = */ body,
|
/* headers = */
|
||||||
/* redirects = */ emptyList<String>()
|
HeadersMultiMap(),
|
||||||
|
/* trailers = */
|
||||||
|
HeadersMultiMap(),
|
||||||
|
/* cookies = */
|
||||||
|
emptyList<String>(),
|
||||||
|
/* body = */
|
||||||
|
body,
|
||||||
|
/* redirects = */
|
||||||
|
emptyList<String>(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,8 +43,8 @@ class FakeRequestSender(
|
|||||||
VertxRestRequestLogger(
|
VertxRestRequestLogger(
|
||||||
responseLogMaxSize = null,
|
responseLogMaxSize = null,
|
||||||
requestResponseLogLevel = Level.DEBUG,
|
requestResponseLogLevel = Level.DEBUG,
|
||||||
log = LogManager.getLogger(FakeRequestSender::class.java)
|
log = LogManager.getLogger(FakeRequestSender::class.java),
|
||||||
)
|
),
|
||||||
) : VertxHttpRequestSender {
|
) : VertxHttpRequestSender {
|
||||||
private val monotonicClock = TimeSource.Monotonic
|
private val monotonicClock = TimeSource.Monotonic
|
||||||
private var lastRequestTime = monotonicClock.markNow()
|
private var lastRequestTime = monotonicClock.markNow()
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class StaticVertxHttpRequestRateLimiterTest {
|
|||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
requestSender = reqSender,
|
requestSender = reqSender,
|
||||||
rateLimitBackoffDelay = rateLimitBackoffDelay,
|
rateLimitBackoffDelay = rateLimitBackoffDelay,
|
||||||
requestLogFormatter = VertxRestLoggingFormatter()
|
requestLogFormatter = VertxRestLoggingFormatter(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ class VertxHttpRequestRateLimiterAndRetryTest {
|
|||||||
requestRetryConfig = RetryConfig(
|
requestRetryConfig = RetryConfig(
|
||||||
maxRetries = 5u,
|
maxRetries = 5u,
|
||||||
backoffDelay = 10.milliseconds,
|
backoffDelay = 10.milliseconds,
|
||||||
timeout = rateLimitBackoffDelay * 30
|
timeout = rateLimitBackoffDelay * 30,
|
||||||
),
|
),
|
||||||
rateLimitBackoffDelay = rateLimitBackoffDelay,
|
rateLimitBackoffDelay = rateLimitBackoffDelay,
|
||||||
logFormatter = VertxRestLoggingFormatter(responseLogMaxSize = 1000u)
|
logFormatter = VertxRestLoggingFormatter(responseLogMaxSize = 1000u),
|
||||||
)
|
)
|
||||||
// Warn: this does not work in io.github.hakky54:logcaptor
|
// Warn: this does not work in io.github.hakky54:logcaptor
|
||||||
// don't have time to dig into it now. disabling it for now
|
// don't have time to dig into it now. disabling it for now
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class VertxRestLoggingFormatterTest {
|
|||||||
val request = WebClient.create(
|
val request = WebClient.create(
|
||||||
Vertx.vertx(),
|
Vertx.vertx(),
|
||||||
WebClientOptions()
|
WebClientOptions()
|
||||||
.setDefaultsFrom(URI("http://service:9876/"))
|
.setDefaultsFrom(URI("http://service:9876/")),
|
||||||
)
|
)
|
||||||
.get("/users/1?appKey=SOME_APP_KEY")
|
.get("/users/1?appKey=SOME_APP_KEY")
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ class VertxRestLoggingFormatterTest {
|
|||||||
return VertxRestLoggingFormatter(
|
return VertxRestLoggingFormatter(
|
||||||
includeFullUri = includeFullUri,
|
includeFullUri = includeFullUri,
|
||||||
uriTransformer = { it.replace("SOME_APP_KEY", "***") },
|
uriTransformer = { it.replace("SOME_APP_KEY", "***") },
|
||||||
responseLogMaxSize = null
|
responseLogMaxSize = null,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ class VertxRestLoggingFormatterTest {
|
|||||||
val response = httpResponse(
|
val response = httpResponse(
|
||||||
statusCode = 200,
|
statusCode = 200,
|
||||||
statusMessage = "OK",
|
statusMessage = "OK",
|
||||||
body = Buffer.buffer("some-response-body")
|
body = Buffer.buffer("some-response-body"),
|
||||||
)
|
)
|
||||||
|
|
||||||
assertThat(formatter(includeFullUri = false).toLogString(request, response))
|
assertThat(formatter(includeFullUri = false).toLogString(request, response))
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class VertxRestRequestLoggerTest {
|
|||||||
override fun toLogString(
|
override fun toLogString(
|
||||||
request: HttpRequest<Buffer>,
|
request: HttpRequest<Buffer>,
|
||||||
response: HttpResponse<Buffer>?,
|
response: HttpResponse<Buffer>?,
|
||||||
failureCause: Throwable?
|
failureCause: Throwable?,
|
||||||
): String {
|
): String {
|
||||||
return "response-log-string"
|
return "response-log-string"
|
||||||
}
|
}
|
||||||
@@ -29,14 +29,14 @@ class VertxRestRequestLoggerTest {
|
|||||||
|
|
||||||
fun setUpLogger(
|
fun setUpLogger(
|
||||||
// we need to use a different logger name for each test
|
// 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> {
|
): Pair<VertxRestRequestLogger, LogCaptor> {
|
||||||
val logCaptor: LogCaptor = LogCaptor.forName(loggerName)
|
val logCaptor: LogCaptor = LogCaptor.forName(loggerName)
|
||||||
return VertxRestRequestLogger(
|
return VertxRestRequestLogger(
|
||||||
log = LogManager.getLogger(loggerName),
|
log = LogManager.getLogger(loggerName),
|
||||||
logFormatter = FakeLogFormatter(),
|
logFormatter = FakeLogFormatter(),
|
||||||
requestResponseLogLevel = Level.TRACE,
|
requestResponseLogLevel = Level.TRACE,
|
||||||
failuresLogLevel = Level.DEBUG
|
failuresLogLevel = Level.DEBUG,
|
||||||
) to logCaptor
|
) to logCaptor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,13 +32,13 @@ class BlobScanClientTest {
|
|||||||
fun setUp(vertx: Vertx) {
|
fun setUp(vertx: Vertx) {
|
||||||
wiremock = WireMockServer(
|
wiremock = WireMockServer(
|
||||||
WireMockConfiguration.options()
|
WireMockConfiguration.options()
|
||||||
.dynamicPort()
|
.dynamicPort(),
|
||||||
)
|
)
|
||||||
.apply {
|
.apply {
|
||||||
addMockServiceRequestListener(object : RequestListener {
|
addMockServiceRequestListener(object : RequestListener {
|
||||||
override fun requestReceived(
|
override fun requestReceived(
|
||||||
request: com.github.tomakehurst.wiremock.http.Request,
|
request: com.github.tomakehurst.wiremock.http.Request,
|
||||||
response: com.github.tomakehurst.wiremock.http.Response
|
response: com.github.tomakehurst.wiremock.http.Response,
|
||||||
) {
|
) {
|
||||||
// to debug
|
// to debug
|
||||||
// println("request: ${request.url}")
|
// println("request: ${request.url}")
|
||||||
@@ -55,8 +55,8 @@ class BlobScanClientTest {
|
|||||||
requestRetryConfig = RetryConfig(
|
requestRetryConfig = RetryConfig(
|
||||||
backoffDelay = 10.milliseconds,
|
backoffDelay = 10.milliseconds,
|
||||||
maxRetries = 5u,
|
maxRetries = 5u,
|
||||||
timeout = 5.seconds
|
timeout = 5.seconds,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,8 +78,8 @@ class BlobScanClientTest {
|
|||||||
.willReturn(
|
.willReturn(
|
||||||
WireMock.ok()
|
WireMock.ok()
|
||||||
.withHeader("Content-type", "application/json")
|
.withHeader("Content-type", "application/json")
|
||||||
.withBody(successResponseBody(blobId, blobData))
|
.withBody(successResponseBody(blobId, blobData)),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
assertThat(blobScanClient.getBlobById(blobId).get().encodeHex()).isEqualTo(blobData)
|
assertThat(blobScanClient.getBlobById(blobId).get().encodeHex()).isEqualTo(blobData)
|
||||||
@@ -99,9 +99,9 @@ class BlobScanClientTest {
|
|||||||
.withBody(
|
.withBody(
|
||||||
"""
|
"""
|
||||||
{"message":"No blob with versioned hash or kzg commitment '$blobId'.","code":"NOT_FOUND"}
|
{"message":"No blob with versioned hash or kzg commitment '$blobId'.","code":"NOT_FOUND"}
|
||||||
""".trimIndent()
|
""".trimIndent(),
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
assertThatThrownBy { blobScanClient.getBlobById(blobId).get() }
|
assertThatThrownBy { blobScanClient.getBlobById(blobId).get() }
|
||||||
@@ -117,22 +117,22 @@ class BlobScanClientTest {
|
|||||||
WireMock.get("/blobs/$blobId")
|
WireMock.get("/blobs/$blobId")
|
||||||
.inScenario("SERVER_ERROR")
|
.inScenario("SERVER_ERROR")
|
||||||
.willReturn(WireMock.status(503))
|
.willReturn(WireMock.status(503))
|
||||||
.willSetStateTo("SERVER_ERROR_1")
|
.willSetStateTo("SERVER_ERROR_1"),
|
||||||
)
|
)
|
||||||
wiremock.stubFor(
|
wiremock.stubFor(
|
||||||
WireMock.get("/blobs/$blobId")
|
WireMock.get("/blobs/$blobId")
|
||||||
.inScenario("SERVER_ERROR")
|
.inScenario("SERVER_ERROR")
|
||||||
.whenScenarioStateIs("SERVER_ERROR_1")
|
.whenScenarioStateIs("SERVER_ERROR_1")
|
||||||
.willReturn(WireMock.status(503))
|
.willReturn(WireMock.status(503))
|
||||||
.willSetStateTo("SERVER_OK")
|
.willSetStateTo("SERVER_OK"),
|
||||||
)
|
)
|
||||||
wiremock.stubFor(
|
wiremock.stubFor(
|
||||||
WireMock.get("/blobs/$blobId")
|
WireMock.get("/blobs/$blobId")
|
||||||
.inScenario("SERVER_ERROR")
|
.inScenario("SERVER_ERROR")
|
||||||
.whenScenarioStateIs("SERVER_OK")
|
.whenScenarioStateIs("SERVER_OK")
|
||||||
.willReturn(
|
.willReturn(
|
||||||
WireMock.okJson(successResponseBody(blobId, blobData))
|
WireMock.okJson(successResponseBody(blobId, blobData)),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
assertThat(blobScanClient.getBlobById(blobId).get().encodeHex()).isEqualTo(blobData)
|
assertThat(blobScanClient.getBlobById(blobId).get().encodeHex()).isEqualTo(blobData)
|
||||||
@@ -140,7 +140,7 @@ class BlobScanClientTest {
|
|||||||
|
|
||||||
private fun successResponseBody(
|
private fun successResponseBody(
|
||||||
blobId: String,
|
blobId: String,
|
||||||
blobData: String
|
blobData: String,
|
||||||
): String {
|
): String {
|
||||||
return """
|
return """
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import tech.pegasys.teku.infrastructure.async.SafeFuture
|
|||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
class VertxTransactionDetailsClient internal constructor(
|
class VertxTransactionDetailsClient internal constructor(
|
||||||
private val jsonRpcClient: JsonRpcV2Client
|
private val jsonRpcClient: JsonRpcV2Client,
|
||||||
) : TransactionDetailsClient {
|
) : TransactionDetailsClient {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -21,14 +21,14 @@ class VertxTransactionDetailsClient internal constructor(
|
|||||||
jsonRpcClientFactory: JsonRpcClientFactory,
|
jsonRpcClientFactory: JsonRpcClientFactory,
|
||||||
endpoint: URI,
|
endpoint: URI,
|
||||||
retryConfig: RequestRetryConfig,
|
retryConfig: RequestRetryConfig,
|
||||||
logger: Logger = LogManager.getLogger(TransactionDetailsClient::class.java)
|
logger: Logger = LogManager.getLogger(TransactionDetailsClient::class.java),
|
||||||
): VertxTransactionDetailsClient {
|
): VertxTransactionDetailsClient {
|
||||||
return VertxTransactionDetailsClient(
|
return VertxTransactionDetailsClient(
|
||||||
jsonRpcClientFactory.createJsonRpcV2Client(
|
jsonRpcClientFactory.createJsonRpcV2Client(
|
||||||
endpoints = listOf(endpoint),
|
endpoints = listOf(endpoint),
|
||||||
retryConfig = retryConfig,
|
retryConfig = retryConfig,
|
||||||
log = logger
|
log = logger,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ class VertxTransactionDetailsClient internal constructor(
|
|||||||
?.toList()
|
?.toList()
|
||||||
?.map { it.asText().decodeHex() }
|
?.map { it.asText().decodeHex() }
|
||||||
?: emptyList()
|
?: emptyList()
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class StateRecoveryE2ETest {
|
|||||||
fun beforeEach(vertx: Vertx) {
|
fun beforeEach(vertx: Vertx) {
|
||||||
val jsonRpcFactory = VertxHttpJsonRpcClientFactory(
|
val jsonRpcFactory = VertxHttpJsonRpcClientFactory(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
metricsFacade = MicrometerMetricsFacade(SimpleMeterRegistry())
|
metricsFacade = MicrometerMetricsFacade(SimpleMeterRegistry()),
|
||||||
)
|
)
|
||||||
|
|
||||||
stateManagerClient = StateManagerV1JsonRpcClient.create(
|
stateManagerClient = StateManagerV1JsonRpcClient.create(
|
||||||
@@ -63,10 +63,10 @@ class StateRecoveryE2ETest {
|
|||||||
maxInflightRequestsPerClient = 1U,
|
maxInflightRequestsPerClient = 1U,
|
||||||
requestRetry = RequestRetryConfig(
|
requestRetry = RequestRetryConfig(
|
||||||
backoffDelay = 10.milliseconds,
|
backoffDelay = 10.milliseconds,
|
||||||
timeout = 2.seconds
|
timeout = 2.seconds,
|
||||||
),
|
),
|
||||||
zkStateManagerVersion = "2.3.0",
|
zkStateManagerVersion = "2.3.0",
|
||||||
logger = LogManager.getLogger("test.clients.l1.state-manager")
|
logger = LogManager.getLogger("test.clients.l1.state-manager"),
|
||||||
)
|
)
|
||||||
|
|
||||||
configureLoggers(
|
configureLoggers(
|
||||||
@@ -80,7 +80,7 @@ class StateRecoveryE2ETest {
|
|||||||
"test.clients.l1.linea-contract" to Level.INFO,
|
"test.clients.l1.linea-contract" to Level.INFO,
|
||||||
"test.clients.l1.events-fetcher" to Level.INFO,
|
"test.clients.l1.events-fetcher" to Level.INFO,
|
||||||
"test.clients.l1.blobscan" 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(
|
Runner.executeCommandFailOnNonZeroExitCode(
|
||||||
command = "make start-env-with-staterecovery",
|
command = "make start-env-with-staterecovery",
|
||||||
envVars = mapOf(
|
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()
|
).get()
|
||||||
log.debug("stack restarted")
|
log.debug("stack restarted")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `should recover from middle of chain and be resilient to node restarts`(
|
fun `should recover from middle of chain and be resilient to node restarts`(
|
||||||
vertx: Vertx
|
vertx: Vertx,
|
||||||
) {
|
) {
|
||||||
// Part A:
|
// Part A:
|
||||||
// we shall have multiple finalizations on L1
|
// we shall have multiple finalizations on L1
|
||||||
@@ -128,15 +128,15 @@ class StateRecoveryE2ETest {
|
|||||||
Web3jClientManager.buildL1Client(
|
Web3jClientManager.buildL1Client(
|
||||||
log = LogManager.getLogger("test.clients.l1.events-fetcher"),
|
log = LogManager.getLogger("test.clients.l1.events-fetcher"),
|
||||||
requestResponseLogLevel = Level.TRACE,
|
requestResponseLogLevel = Level.TRACE,
|
||||||
failuresLogLevel = Level.WARN
|
failuresLogLevel = Level.WARN,
|
||||||
),
|
),
|
||||||
requestRetryConfig = RetryConfig.noRetries,
|
requestRetryConfig = RetryConfig.noRetries,
|
||||||
vertx = null
|
vertx = null,
|
||||||
),
|
),
|
||||||
EthLogsSearcherImpl.Config(
|
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)
|
val web3jElClient = createWeb3jHttpClient(executionLayerUrl)
|
||||||
log.info("starting test flow: besu staterecovery block={}", web3jElClient.ethBlockNumber().send().blockNumber)
|
log.info("starting test flow: besu staterecovery block={}", web3jElClient.ethBlockNumber().send().blockNumber)
|
||||||
@@ -167,7 +167,7 @@ class StateRecoveryE2ETest {
|
|||||||
command = "make staterecovery-replay-from-block " +
|
command = "make staterecovery-replay-from-block " +
|
||||||
"L1_ROLLUP_CONTRACT_ADDRESS=$localStackL1ContractAddress " +
|
"L1_ROLLUP_CONTRACT_ADDRESS=$localStackL1ContractAddress " +
|
||||||
"STATERECOVERY_OVERRIDE_START_BLOCK_NUMBER=$stateRecoveryStartBlockNumber",
|
"STATERECOVERY_OVERRIDE_START_BLOCK_NUMBER=$stateRecoveryStartBlockNumber",
|
||||||
log = log
|
log = log,
|
||||||
).get()
|
).get()
|
||||||
// No Errors should be logged in Besu
|
// No Errors should be logged in Besu
|
||||||
assertThat(getBesuErrorLogs()).isEmpty()
|
assertThat(getBesuErrorLogs()).isEmpty()
|
||||||
@@ -178,7 +178,7 @@ class StateRecoveryE2ETest {
|
|||||||
web3jElClient,
|
web3jElClient,
|
||||||
stateManagerClient,
|
stateManagerClient,
|
||||||
lastFinalizationA.event.endBlockNumber,
|
lastFinalizationA.event.endBlockNumber,
|
||||||
lastFinalizationA.event.finalStateRootHash
|
lastFinalizationA.event.finalStateRootHash,
|
||||||
)
|
)
|
||||||
// No Errors should be logged in Besu
|
// No Errors should be logged in Besu
|
||||||
assertThat(getBesuErrorLogs()).isEmpty()
|
assertThat(getBesuErrorLogs()).isEmpty()
|
||||||
@@ -200,7 +200,7 @@ class StateRecoveryE2ETest {
|
|||||||
web3jElClient,
|
web3jElClient,
|
||||||
stateManagerClient,
|
stateManagerClient,
|
||||||
lastFinalizationB.event.endBlockNumber,
|
lastFinalizationB.event.endBlockNumber,
|
||||||
lastFinalizationB.event.finalStateRootHash
|
lastFinalizationB.event.finalStateRootHash,
|
||||||
)
|
)
|
||||||
// No Errors should be logged in Besu
|
// No Errors should be logged in Besu
|
||||||
assertThat(getBesuErrorLogs()).isEmpty()
|
assertThat(getBesuErrorLogs()).isEmpty()
|
||||||
@@ -210,7 +210,7 @@ class StateRecoveryE2ETest {
|
|||||||
log.info("Restarting zkbesu-shomei node")
|
log.info("Restarting zkbesu-shomei node")
|
||||||
execCommandAndAssertSuccess(
|
execCommandAndAssertSuccess(
|
||||||
command = "docker restart -s 9 zkbesu-shomei-sr",
|
command = "docker restart -s 9 zkbesu-shomei-sr",
|
||||||
log = log
|
log = log,
|
||||||
).get()
|
).get()
|
||||||
// No Errors should be logged in Besu
|
// No Errors should be logged in Besu
|
||||||
assertThat(getBesuErrorLogs()).isEmpty()
|
assertThat(getBesuErrorLogs()).isEmpty()
|
||||||
@@ -237,31 +237,36 @@ class StateRecoveryE2ETest {
|
|||||||
web3jElClient,
|
web3jElClient,
|
||||||
stateManagerClient,
|
stateManagerClient,
|
||||||
lastFinalizationC.event.endBlockNumber,
|
lastFinalizationC.event.endBlockNumber,
|
||||||
lastFinalizationC.event.finalStateRootHash
|
lastFinalizationC.event.finalStateRootHash,
|
||||||
)
|
)
|
||||||
// No Errors should be logged in Besu
|
// No Errors should be logged in Besu
|
||||||
assertThat(getBesuErrorLogs()).isEmpty()
|
assertThat(getBesuErrorLogs()).isEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendTxToL2(
|
private fun sendTxToL2(
|
||||||
keepSendingPredicate: () -> Boolean
|
keepSendingPredicate: () -> Boolean,
|
||||||
) {
|
) {
|
||||||
val account = L2AccountManager.generateAccount()
|
val account = L2AccountManager.generateAccount()
|
||||||
val txManager = L2AccountManager.getTransactionManager(account)
|
val txManager = L2AccountManager.getTransactionManager(account)
|
||||||
Thread {
|
Thread {
|
||||||
while (keepSendingPredicate()) {
|
while (keepSendingPredicate()) {
|
||||||
val txHash = txManager.sendTransaction(
|
val txHash = txManager.sendTransaction(
|
||||||
/*gasPrice*/ 150UL.gwei.toBigInteger(),
|
/*gasPrice*/
|
||||||
/*gasLimit*/ 25_000UL.toBigInteger(),
|
150UL.gwei.toBigInteger(),
|
||||||
/*to*/ account.address,
|
/*gasLimit*/
|
||||||
/*data*/ "",
|
25_000UL.toBigInteger(),
|
||||||
/*value*/ 1UL.toBigInteger()
|
/*to*/
|
||||||
|
account.address,
|
||||||
|
/*data*/
|
||||||
|
"",
|
||||||
|
/*value*/
|
||||||
|
1UL.toBigInteger(),
|
||||||
).transactionHash
|
).transactionHash
|
||||||
log.trace("sent tx to L2, txHash={}", txHash)
|
log.trace("sent tx to L2, txHash={}", txHash)
|
||||||
Web3jClientManager.l2Client.waitForTxReceipt(
|
Web3jClientManager.l2Client.waitForTxReceipt(
|
||||||
txHash = txHash,
|
txHash = txHash,
|
||||||
timeout = 5.seconds,
|
timeout = 5.seconds,
|
||||||
pollingInterval = 500.milliseconds
|
pollingInterval = 500.milliseconds,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}.start()
|
}.start()
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class LineaSubmissionEventsClientIntTest {
|
|||||||
private lateinit var submissionEventsFetcher: LineaRollupSubmissionEventsClient
|
private lateinit var submissionEventsFetcher: LineaRollupSubmissionEventsClient
|
||||||
|
|
||||||
private fun setupTest(
|
private fun setupTest(
|
||||||
vertx: Vertx
|
vertx: Vertx,
|
||||||
) {
|
) {
|
||||||
configureLoggers(
|
configureLoggers(
|
||||||
rootLevel = Level.INFO,
|
rootLevel = Level.INFO,
|
||||||
@@ -47,7 +47,7 @@ class LineaSubmissionEventsClientIntTest {
|
|||||||
"test.clients.l1.executionlayer" to Level.INFO,
|
"test.clients.l1.executionlayer" to Level.INFO,
|
||||||
"test.clients.l1.web3j-default" to Level.INFO,
|
"test.clients.l1.web3j-default" to Level.INFO,
|
||||||
"test.clients.l1.linea-contract" 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()
|
val rollupDeploymentFuture = ContractsManager.get()
|
||||||
@@ -57,13 +57,13 @@ class LineaSubmissionEventsClientIntTest {
|
|||||||
blobsResponsesDir = "$testDataDir/compression/responses",
|
blobsResponsesDir = "$testDataDir/compression/responses",
|
||||||
aggregationsResponsesDir = "$testDataDir/aggregation/responses",
|
aggregationsResponsesDir = "$testDataDir/aggregation/responses",
|
||||||
numberOfAggregations = 7,
|
numberOfAggregations = 7,
|
||||||
extraBlobsWithoutAggregation = 3
|
extraBlobsWithoutAggregation = 3,
|
||||||
)
|
)
|
||||||
// wait smc deployment finishes
|
// wait smc deployment finishes
|
||||||
rollupDeploymentResult = rollupDeploymentFuture.get()
|
rollupDeploymentResult = rollupDeploymentFuture.get()
|
||||||
submissionEventsFetcher = createSubmissionEventsClient(
|
submissionEventsFetcher = createSubmissionEventsClient(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
contractAddress = rollupDeploymentResult.contractAddress
|
contractAddress = rollupDeploymentResult.contractAddress,
|
||||||
)
|
)
|
||||||
|
|
||||||
submitBlobsAndAggregationsAndWaitExecution(
|
submitBlobsAndAggregationsAndWaitExecution(
|
||||||
@@ -71,24 +71,24 @@ class LineaSubmissionEventsClientIntTest {
|
|||||||
contractClientForAggregationSubmission = connectToLineaRollupContract(
|
contractClientForAggregationSubmission = connectToLineaRollupContract(
|
||||||
contractAddress = rollupDeploymentResult.contractAddress,
|
contractAddress = rollupDeploymentResult.contractAddress,
|
||||||
transactionManager = rollupDeploymentResult.rollupOperators[1].txManager,
|
transactionManager = rollupDeploymentResult.rollupOperators[1].txManager,
|
||||||
smartContractErrors = lineaRollupContractErrors
|
smartContractErrors = lineaRollupContractErrors,
|
||||||
),
|
),
|
||||||
aggregationsAndBlobs = aggregationsAndBlobs,
|
aggregationsAndBlobs = aggregationsAndBlobs,
|
||||||
blobChunksMaxSize = 9,
|
blobChunksMaxSize = 9,
|
||||||
l1Web3jClient = Web3jClientManager.l1Client,
|
l1Web3jClient = Web3jClientManager.l1Client,
|
||||||
waitTimeout = 4.minutes
|
waitTimeout = 4.minutes,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createSubmissionEventsClient(
|
private fun createSubmissionEventsClient(
|
||||||
vertx: Vertx,
|
vertx: Vertx,
|
||||||
contractAddress: String
|
contractAddress: String,
|
||||||
): LineaRollupSubmissionEventsClient {
|
): LineaRollupSubmissionEventsClient {
|
||||||
val log = LogManager.getLogger("test.clients.l1.events-fetcher")
|
val log = LogManager.getLogger("test.clients.l1.events-fetcher")
|
||||||
val eventsFetcherWeb3jClient = Web3jClientManager.buildL1Client(
|
val eventsFetcherWeb3jClient = Web3jClientManager.buildL1Client(
|
||||||
log = log,
|
log = log,
|
||||||
requestResponseLogLevel = Level.DEBUG,
|
requestResponseLogLevel = Level.DEBUG,
|
||||||
failuresLogLevel = Level.WARN
|
failuresLogLevel = Level.WARN,
|
||||||
)
|
)
|
||||||
return LineaSubmissionEventsClientImpl(
|
return LineaSubmissionEventsClientImpl(
|
||||||
logsSearcher = EthLogsSearcherImpl(
|
logsSearcher = EthLogsSearcherImpl(
|
||||||
@@ -96,16 +96,16 @@ class LineaSubmissionEventsClientIntTest {
|
|||||||
ethApiClient = createEthApiClient(
|
ethApiClient = createEthApiClient(
|
||||||
web3jClient = eventsFetcherWeb3jClient,
|
web3jClient = eventsFetcherWeb3jClient,
|
||||||
requestRetryConfig = RetryConfig.noRetries,
|
requestRetryConfig = RetryConfig.noRetries,
|
||||||
vertx = null
|
vertx = null,
|
||||||
),
|
),
|
||||||
config = EthLogsSearcherImpl.Config(
|
config = EthLogsSearcherImpl.Config(
|
||||||
loopSuccessBackoffDelay = 1.milliseconds
|
loopSuccessBackoffDelay = 1.milliseconds,
|
||||||
),
|
),
|
||||||
log = log
|
log = log,
|
||||||
),
|
),
|
||||||
smartContractAddress = contractAddress,
|
smartContractAddress = contractAddress,
|
||||||
l1LatestSearchBlock = BlockParameter.Tag.LATEST,
|
l1LatestSearchBlock = BlockParameter.Tag.LATEST,
|
||||||
logsBlockChunkSize = 100
|
logsBlockChunkSize = 100,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,8 +125,8 @@ class LineaSubmissionEventsClientIntTest {
|
|||||||
submissionEventsFetcher
|
submissionEventsFetcher
|
||||||
.findFinalizationAndDataSubmissionV3Events(
|
.findFinalizationAndDataSubmissionV3Events(
|
||||||
fromL1BlockNumber = BlockParameter.Tag.EARLIEST,
|
fromL1BlockNumber = BlockParameter.Tag.EARLIEST,
|
||||||
finalizationStartBlockNumber = expectedFinalizationEvent.startBlockNumber
|
finalizationStartBlockNumber = expectedFinalizationEvent.startBlockNumber,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
.succeedsWithin(1.minutes.toJavaDuration())
|
.succeedsWithin(1.minutes.toJavaDuration())
|
||||||
.extracting { submissionEvents ->
|
.extracting { submissionEvents ->
|
||||||
@@ -146,8 +146,8 @@ class LineaSubmissionEventsClientIntTest {
|
|||||||
submissionEventsFetcher
|
submissionEventsFetcher
|
||||||
.findFinalizationAndDataSubmissionV3Events(
|
.findFinalizationAndDataSubmissionV3Events(
|
||||||
fromL1BlockNumber = BlockParameter.Tag.EARLIEST,
|
fromL1BlockNumber = BlockParameter.Tag.EARLIEST,
|
||||||
finalizationStartBlockNumber = invalidStartBlockNumber
|
finalizationStartBlockNumber = invalidStartBlockNumber,
|
||||||
).get()
|
).get(),
|
||||||
)
|
)
|
||||||
.isNull()
|
.isNull()
|
||||||
}
|
}
|
||||||
@@ -159,7 +159,7 @@ class LineaSubmissionEventsClientIntTest {
|
|||||||
submissionEventsFetcher
|
submissionEventsFetcher
|
||||||
.findFinalizationAndDataSubmissionV3EventsContainingL2BlockNumber(
|
.findFinalizationAndDataSubmissionV3EventsContainingL2BlockNumber(
|
||||||
fromL1BlockNumber = BlockParameter.Tag.EARLIEST,
|
fromL1BlockNumber = BlockParameter.Tag.EARLIEST,
|
||||||
l2BlockNumber = invalidStartBlockNumber
|
l2BlockNumber = invalidStartBlockNumber,
|
||||||
).get()
|
).get()
|
||||||
.also { result ->
|
.also { result ->
|
||||||
assertThat(result).isNotNull
|
assertThat(result).isNotNull
|
||||||
@@ -169,7 +169,7 @@ class LineaSubmissionEventsClientIntTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getExpectedSubmissionEventsFromRecords(
|
private fun getExpectedSubmissionEventsFromRecords(
|
||||||
aggregationsAndBlobs: List<AggregationAndBlobs>
|
aggregationsAndBlobs: List<AggregationAndBlobs>,
|
||||||
): List<Pair<DataFinalizedV3, List<DataSubmittedV3>>> {
|
): List<Pair<DataFinalizedV3, List<DataSubmittedV3>>> {
|
||||||
return aggregationsAndBlobs
|
return aggregationsAndBlobs
|
||||||
.filter { it.aggregation != null }
|
.filter { it.aggregation != null }
|
||||||
@@ -180,7 +180,7 @@ class LineaSubmissionEventsClientIntTest {
|
|||||||
DataSubmittedV3(
|
DataSubmittedV3(
|
||||||
parentShnarf = blobsChunk.first().blobCompressionProof!!.prevShnarf,
|
parentShnarf = blobsChunk.first().blobCompressionProof!!.prevShnarf,
|
||||||
shnarf = blobsChunk.last().expectedShnarf,
|
shnarf = blobsChunk.last().expectedShnarf,
|
||||||
finalStateRootHash = blobsChunk.last().blobCompressionProof!!.finalStateRootHash
|
finalStateRootHash = blobsChunk.last().blobCompressionProof!!.finalStateRootHash,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ class LineaSubmissionEventsClientIntTest {
|
|||||||
endBlockNumber = aggregation.endBlockNumber,
|
endBlockNumber = aggregation.endBlockNumber,
|
||||||
shnarf = aggBlobs.last().expectedShnarf,
|
shnarf = aggBlobs.last().expectedShnarf,
|
||||||
parentStateRootHash = aggBlobs.first().blobCompressionProof!!.parentStateRootHash,
|
parentStateRootHash = aggBlobs.first().blobCompressionProof!!.parentStateRootHash,
|
||||||
finalStateRootHash = aggBlobs.last().blobCompressionProof!!.finalStateRootHash
|
finalStateRootHash = aggBlobs.last().blobCompressionProof!!.finalStateRootHash,
|
||||||
) to expectedDataSubmittedEvents
|
) to expectedDataSubmittedEvents
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,12 +65,12 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
|
|||||||
blobsResponsesDir = "$testDataDir/compression/responses",
|
blobsResponsesDir = "$testDataDir/compression/responses",
|
||||||
aggregationsResponsesDir = "$testDataDir/aggregation/responses",
|
aggregationsResponsesDir = "$testDataDir/aggregation/responses",
|
||||||
numberOfAggregations = 4,
|
numberOfAggregations = 4,
|
||||||
extraBlobsWithoutAggregation = 0
|
extraBlobsWithoutAggregation = 0,
|
||||||
)
|
)
|
||||||
fakeExecutionLayerClient = FakeExecutionLayerClient(
|
fakeExecutionLayerClient = FakeExecutionLayerClient(
|
||||||
headBlock = BlockNumberAndHash(number = 0uL, hash = ByteArray(32) { 0 }),
|
headBlock = BlockNumberAndHash(number = 0uL, hash = ByteArray(32) { 0 }),
|
||||||
initialStateRecoverStartBlockNumber = null,
|
initialStateRecoverStartBlockNumber = null,
|
||||||
loggerName = "test.fake.clients.l1.fake-execution-layer"
|
loggerName = "test.fake.clients.l1.fake-execution-layer",
|
||||||
)
|
)
|
||||||
fakeStateManagerClient =
|
fakeStateManagerClient =
|
||||||
FakeStateManagerClientBasedOnBlobsRecords(blobRecords = aggregationsAndBlobs.flatMap { it.blobs })
|
FakeStateManagerClientBasedOnBlobsRecords(blobRecords = aggregationsAndBlobs.flatMap { it.blobs })
|
||||||
@@ -84,7 +84,7 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
|
|||||||
l1PollingInterval = 100.milliseconds,
|
l1PollingInterval = 100.milliseconds,
|
||||||
l1getLogsChunkSize = 1000u,
|
l1getLogsChunkSize = 1000u,
|
||||||
executionClientPollingInterval = 1.seconds,
|
executionClientPollingInterval = 1.seconds,
|
||||||
smartContractAddress = rollupDeploymentResult.contractAddress
|
smartContractAddress = rollupDeploymentResult.contractAddress,
|
||||||
)
|
)
|
||||||
|
|
||||||
appClients = createAppClients(
|
appClients = createAppClients(
|
||||||
@@ -93,14 +93,14 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
|
|||||||
l1RpcEndpoint = URI(l1RpcUrl),
|
l1RpcEndpoint = URI(l1RpcUrl),
|
||||||
l1RequestRetryConfig = RetryConfig(backoffDelay = 2.seconds),
|
l1RequestRetryConfig = RetryConfig(backoffDelay = 2.seconds),
|
||||||
blobScanEndpoint = URI(blobScanUrl),
|
blobScanEndpoint = URI(blobScanUrl),
|
||||||
stateManagerClientEndpoint = URI("http://it-does-not-matter:5432")
|
stateManagerClientEndpoint = URI("http://it-does-not-matter:5432"),
|
||||||
)
|
)
|
||||||
|
|
||||||
contractClientForBlobSubmissions = rollupDeploymentResult.rollupOperatorClient
|
contractClientForBlobSubmissions = rollupDeploymentResult.rollupOperatorClient
|
||||||
contractClientForAggregationSubmissions = connectToLineaRollupContract(
|
contractClientForAggregationSubmissions = connectToLineaRollupContract(
|
||||||
rollupDeploymentResult.contractAddress,
|
rollupDeploymentResult.contractAddress,
|
||||||
rollupDeploymentResult.rollupOperators[1].txManager,
|
rollupDeploymentResult.rollupOperators[1].txManager,
|
||||||
smartContractErrors = lineaRollupContractErrors
|
smartContractErrors = lineaRollupContractErrors,
|
||||||
)
|
)
|
||||||
|
|
||||||
configureLoggers(
|
configureLoggers(
|
||||||
@@ -113,12 +113,12 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
|
|||||||
"test.fake.clients.l1.fake-execution-layer" to Level.DEBUG,
|
"test.fake.clients.l1.fake-execution-layer" to Level.DEBUG,
|
||||||
"test.clients.l1.web3j-default" to Level.INFO,
|
"test.clients.l1.web3j-default" to Level.INFO,
|
||||||
"test.clients.l1.web3j.receipt-poller" 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(
|
fun instantiateStateRecoveryApp(
|
||||||
debugForceSyncStopBlockNumber: ULong? = null
|
debugForceSyncStopBlockNumber: ULong? = null,
|
||||||
): StateRecoveryApp {
|
): StateRecoveryApp {
|
||||||
return StateRecoveryApp(
|
return StateRecoveryApp(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
@@ -130,15 +130,15 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
|
|||||||
blockHeaderStaticFields = BlockHeaderStaticFields.localDev,
|
blockHeaderStaticFields = BlockHeaderStaticFields.localDev,
|
||||||
lineaContractClient = appClients.lineaContractClient,
|
lineaContractClient = appClients.lineaContractClient,
|
||||||
config = appConfigs.copy(
|
config = appConfigs.copy(
|
||||||
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber
|
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun submitDataToL1ContactAndWaitExecution(
|
private fun submitDataToL1ContactAndWaitExecution(
|
||||||
aggregationsAndBlobs: List<AggregationAndBlobs> = this.aggregationsAndBlobs,
|
aggregationsAndBlobs: List<AggregationAndBlobs> = this.aggregationsAndBlobs,
|
||||||
blobChunksSize: Int = 9,
|
blobChunksSize: Int = 9,
|
||||||
waitTimeout: Duration = 4.minutes
|
waitTimeout: Duration = 4.minutes,
|
||||||
) {
|
) {
|
||||||
submitBlobsAndAggregationsAndWaitExecution(
|
submitBlobsAndAggregationsAndWaitExecution(
|
||||||
contractClientForBlobSubmission = contractClientForBlobSubmissions,
|
contractClientForBlobSubmission = contractClientForBlobSubmissions,
|
||||||
@@ -148,8 +148,8 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
|
|||||||
waitTimeout = waitTimeout,
|
waitTimeout = waitTimeout,
|
||||||
l1Web3jClient = createWeb3jHttpClient(
|
l1Web3jClient = createWeb3jHttpClient(
|
||||||
rpcUrl = l1RpcUrl,
|
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. when state recovery enabled:
|
||||||
2.1 recoveryStartBlockNumber > headBlockNumber: pull for head block number until is reached and start recovery there
|
2.1 recoveryStartBlockNumber > headBlockNumber: pull for head block number until is reached and start recovery there
|
||||||
2.2 recoveryStartBlockNumber <= headBlockNumber: resume recovery from headBlockNumber
|
2.2 recoveryStartBlockNumber <= headBlockNumber: resume recovery from headBlockNumber
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
fun `when state recovery disabled and is starting from genesis`() {
|
fun `when state recovery disabled and is starting from genesis`() {
|
||||||
instantiateStateRecoveryApp().start().get()
|
instantiateStateRecoveryApp().start().get()
|
||||||
@@ -180,8 +180,8 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
|
|||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
StateRecoveryStatus(
|
StateRecoveryStatus(
|
||||||
headBlockNumber = lastAggregation!!.endBlockNumber,
|
headBlockNumber = lastAggregation!!.endBlockNumber,
|
||||||
stateRecoverStartBlockNumber = 1UL
|
stateRecoverStartBlockNumber = 1UL,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,16 +204,16 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
|
|||||||
log.debug(
|
log.debug(
|
||||||
"finalizations={} finalizationToStartRecoveryFrom={}",
|
"finalizations={} finalizationToStartRecoveryFrom={}",
|
||||||
aggregationsAndBlobs.map { it.aggregation?.intervalString() },
|
aggregationsAndBlobs.map { it.aggregation?.intervalString() },
|
||||||
finalizationToResumeFrom.intervalString()
|
finalizationToResumeFrom.intervalString(),
|
||||||
)
|
)
|
||||||
|
|
||||||
submitDataToL1ContactAndWaitExecution(
|
submitDataToL1ContactAndWaitExecution(
|
||||||
aggregationsAndBlobs = finalizationsBeforeCutOff
|
aggregationsAndBlobs = finalizationsBeforeCutOff,
|
||||||
)
|
)
|
||||||
|
|
||||||
fakeExecutionLayerClient.headBlock = BlockNumberAndHash(
|
fakeExecutionLayerClient.headBlock = BlockNumberAndHash(
|
||||||
number = 1UL,
|
number = 1UL,
|
||||||
hash = ByteArray(32) { 0 }
|
hash = ByteArray(32) { 0 },
|
||||||
)
|
)
|
||||||
|
|
||||||
val lastFinalizedBlockNumber = finalizationsBeforeCutOff.last().aggregation!!.endBlockNumber
|
val lastFinalizedBlockNumber = finalizationsBeforeCutOff.last().aggregation!!.endBlockNumber
|
||||||
@@ -227,8 +227,8 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
|
|||||||
assertThat(fakeExecutionLayerClient.stateRecoverStatus).isEqualTo(
|
assertThat(fakeExecutionLayerClient.stateRecoverStatus).isEqualTo(
|
||||||
StateRecoveryStatus(
|
StateRecoveryStatus(
|
||||||
headBlockNumber = 1UL,
|
headBlockNumber = 1UL,
|
||||||
stateRecoverStartBlockNumber = expectedStateRecoverStartBlockNumber
|
stateRecoverStartBlockNumber = expectedStateRecoverStartBlockNumber,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
log.info("stateRecoverStatus={}", fakeExecutionLayerClient.stateRecoverStatus)
|
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
|
// simulate that execution client has synced up to the last finalized block through P2P network
|
||||||
fakeExecutionLayerClient.headBlock = BlockNumberAndHash(
|
fakeExecutionLayerClient.headBlock = BlockNumberAndHash(
|
||||||
number = lastFinalizedBlockNumber,
|
number = lastFinalizedBlockNumber,
|
||||||
hash = ByteArray(32) { 0 }
|
hash = ByteArray(32) { 0 },
|
||||||
)
|
)
|
||||||
|
|
||||||
// continue finalizing the rest of the aggregations
|
// continue finalizing the rest of the aggregations
|
||||||
submitDataToL1ContactAndWaitExecution(
|
submitDataToL1ContactAndWaitExecution(
|
||||||
aggregationsAndBlobs = finalizationsAfterCutOff
|
aggregationsAndBlobs = finalizationsAfterCutOff,
|
||||||
)
|
)
|
||||||
|
|
||||||
val lastAggregation = aggregationsAndBlobs.findLast { it.aggregation != null }!!.aggregation
|
val lastAggregation = aggregationsAndBlobs.findLast { it.aggregation != null }!!.aggregation
|
||||||
@@ -277,18 +277,18 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
|
|||||||
log.debug(
|
log.debug(
|
||||||
"finalizations={} finalizationToStartRecoveryFrom={}",
|
"finalizations={} finalizationToStartRecoveryFrom={}",
|
||||||
aggregationsAndBlobs.map { it.aggregation?.intervalString() },
|
aggregationsAndBlobs.map { it.aggregation?.intervalString() },
|
||||||
finalizationToResumeFrom.intervalString()
|
finalizationToResumeFrom.intervalString(),
|
||||||
)
|
)
|
||||||
|
|
||||||
submitDataToL1ContactAndWaitExecution(
|
submitDataToL1ContactAndWaitExecution(
|
||||||
aggregationsAndBlobs = finalizationsBeforeCutOff
|
aggregationsAndBlobs = finalizationsBeforeCutOff,
|
||||||
)
|
)
|
||||||
|
|
||||||
// set execution layer head block after latest finalization
|
// set execution layer head block after latest finalization
|
||||||
val headBlockNumberAtStart = finalizationsBeforeCutOff.last().aggregation!!.endBlockNumber + 1UL
|
val headBlockNumberAtStart = finalizationsBeforeCutOff.last().aggregation!!.endBlockNumber + 1UL
|
||||||
fakeExecutionLayerClient.headBlock = BlockNumberAndHash(
|
fakeExecutionLayerClient.headBlock = BlockNumberAndHash(
|
||||||
number = headBlockNumberAtStart,
|
number = headBlockNumberAtStart,
|
||||||
hash = ByteArray(32) { 0 }
|
hash = ByteArray(32) { 0 },
|
||||||
)
|
)
|
||||||
instantiateStateRecoveryApp().start().get()
|
instantiateStateRecoveryApp().start().get()
|
||||||
await()
|
await()
|
||||||
@@ -298,15 +298,15 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
|
|||||||
assertThat(fakeExecutionLayerClient.stateRecoverStatus).isEqualTo(
|
assertThat(fakeExecutionLayerClient.stateRecoverStatus).isEqualTo(
|
||||||
StateRecoveryStatus(
|
StateRecoveryStatus(
|
||||||
headBlockNumber = headBlockNumberAtStart,
|
headBlockNumber = headBlockNumberAtStart,
|
||||||
stateRecoverStartBlockNumber = headBlockNumberAtStart + 1UL
|
stateRecoverStartBlockNumber = headBlockNumberAtStart + 1UL,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
log.debug("stateRecoverStatus={}", fakeExecutionLayerClient.stateRecoverStatus)
|
log.debug("stateRecoverStatus={}", fakeExecutionLayerClient.stateRecoverStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
// continue finalizing the rest of the aggregations
|
// continue finalizing the rest of the aggregations
|
||||||
submitDataToL1ContactAndWaitExecution(
|
submitDataToL1ContactAndWaitExecution(
|
||||||
aggregationsAndBlobs = finalizationsAfterCutOff
|
aggregationsAndBlobs = finalizationsAfterCutOff,
|
||||||
)
|
)
|
||||||
|
|
||||||
val lastAggregation = aggregationsAndBlobs.findLast { it.aggregation != null }!!.aggregation
|
val lastAggregation = aggregationsAndBlobs.findLast { it.aggregation != null }!!.aggregation
|
||||||
@@ -318,8 +318,8 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
|
|||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
StateRecoveryStatus(
|
StateRecoveryStatus(
|
||||||
headBlockNumber = lastAggregation!!.endBlockNumber,
|
headBlockNumber = lastAggregation!!.endBlockNumber,
|
||||||
stateRecoverStartBlockNumber = headBlockNumberAtStart + 1UL
|
stateRecoverStartBlockNumber = headBlockNumberAtStart + 1UL,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// assert it does not try to import blocks behind the head block
|
// 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`() {
|
fun `should stop recovery as soon as stateroot mismatches`() {
|
||||||
fakeStateManagerClient.setBlockStateRootHash(
|
fakeStateManagerClient.setBlockStateRootHash(
|
||||||
aggregationsAndBlobs[1].aggregation!!.endBlockNumber,
|
aggregationsAndBlobs[1].aggregation!!.endBlockNumber,
|
||||||
ByteArray(32) { 1 }
|
ByteArray(32) { 1 },
|
||||||
)
|
)
|
||||||
log.debug(
|
log.debug(
|
||||||
"aggregations={} forcedMismatchAggregation={}",
|
"aggregations={} forcedMismatchAggregation={}",
|
||||||
aggregationsAndBlobs.map { it.aggregation?.intervalString() },
|
aggregationsAndBlobs.map { it.aggregation?.intervalString() },
|
||||||
aggregationsAndBlobs[1].aggregation!!.intervalString()
|
aggregationsAndBlobs[1].aggregation!!.intervalString(),
|
||||||
)
|
)
|
||||||
|
|
||||||
val stateRecoverApp = instantiateStateRecoveryApp()
|
val stateRecoverApp = instantiateStateRecoveryApp()
|
||||||
@@ -368,7 +368,7 @@ class StateRecoveryAppWithFakeExecutionClientIntTest {
|
|||||||
log.debug(
|
log.debug(
|
||||||
"headBlockNumber={} forceSyncStopBlockNumber={}",
|
"headBlockNumber={} forceSyncStopBlockNumber={}",
|
||||||
fakeExecutionLayerClient.headBlock.number,
|
fakeExecutionLayerClient.headBlock.number,
|
||||||
debugForceSyncStopBlockNumber
|
debugForceSyncStopBlockNumber,
|
||||||
)
|
)
|
||||||
assertThat(fakeExecutionLayerClient.headBlock.number).isGreaterThanOrEqualTo(debugForceSyncStopBlockNumber)
|
assertThat(fakeExecutionLayerClient.headBlock.number).isGreaterThanOrEqualTo(debugForceSyncStopBlockNumber)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class StateRecoveryWithRealBesuAndStateManagerIntTest {
|
|||||||
private val testDataDir = "testdata/coordinator/prover/v3/stateRecovery"
|
private val testDataDir = "testdata/coordinator/prover/v3/stateRecovery"
|
||||||
private val aggregationsAndBlobs: List<AggregationAndBlobs> = loadBlobsAndAggregationsSortedAndGrouped(
|
private val aggregationsAndBlobs: List<AggregationAndBlobs> = loadBlobsAndAggregationsSortedAndGrouped(
|
||||||
blobsResponsesDir = "$testDataDir/compression/responses",
|
blobsResponsesDir = "$testDataDir/compression/responses",
|
||||||
aggregationsResponsesDir = "$testDataDir/aggregation/responses"
|
aggregationsResponsesDir = "$testDataDir/aggregation/responses",
|
||||||
)
|
)
|
||||||
private lateinit var rollupDeploymentResult: LineaRollupDeploymentResult
|
private lateinit var rollupDeploymentResult: LineaRollupDeploymentResult
|
||||||
private lateinit var contractClientForBlobSubmission: LineaRollupSmartContractClient
|
private lateinit var contractClientForBlobSubmission: LineaRollupSmartContractClient
|
||||||
@@ -54,7 +54,7 @@ class StateRecoveryWithRealBesuAndStateManagerIntTest {
|
|||||||
fun beforeEach(vertx: Vertx) {
|
fun beforeEach(vertx: Vertx) {
|
||||||
val jsonRpcFactory = VertxHttpJsonRpcClientFactory(
|
val jsonRpcFactory = VertxHttpJsonRpcClientFactory(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
metricsFacade = MicrometerMetricsFacade(SimpleMeterRegistry())
|
metricsFacade = MicrometerMetricsFacade(SimpleMeterRegistry()),
|
||||||
)
|
)
|
||||||
|
|
||||||
stateManagerClient = StateManagerV1JsonRpcClient.create(
|
stateManagerClient = StateManagerV1JsonRpcClient.create(
|
||||||
@@ -63,10 +63,10 @@ class StateRecoveryWithRealBesuAndStateManagerIntTest {
|
|||||||
maxInflightRequestsPerClient = 1U,
|
maxInflightRequestsPerClient = 1U,
|
||||||
requestRetry = RequestRetryConfig(
|
requestRetry = RequestRetryConfig(
|
||||||
backoffDelay = 1.seconds,
|
backoffDelay = 1.seconds,
|
||||||
timeout = 4.seconds
|
timeout = 4.seconds,
|
||||||
),
|
),
|
||||||
zkStateManagerVersion = "2.3.0",
|
zkStateManagerVersion = "2.3.0",
|
||||||
logger = LogManager.getLogger("test.clients.l1.state-manager")
|
logger = LogManager.getLogger("test.clients.l1.state-manager"),
|
||||||
)
|
)
|
||||||
|
|
||||||
configureLoggers(
|
configureLoggers(
|
||||||
@@ -74,7 +74,7 @@ class StateRecoveryWithRealBesuAndStateManagerIntTest {
|
|||||||
log.name to Level.DEBUG,
|
log.name to Level.DEBUG,
|
||||||
"net.consensys.linea.contract.Web3JContractAsyncHelper" to Level.WARN, // silence noisy gasPrice Caps logs
|
"net.consensys.linea.contract.Web3JContractAsyncHelper" to Level.WARN, // silence noisy gasPrice Caps logs
|
||||||
"test.clients.l1.state-manager" to Level.DEBUG,
|
"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,
|
rollupDeploymentResult.contractAddress,
|
||||||
// index 0 is the first operator in rollupOperatorClient
|
// index 0 is the first operator in rollupOperatorClient
|
||||||
rollupDeploymentResult.rollupOperators[1].txManager,
|
rollupDeploymentResult.rollupOperators[1].txManager,
|
||||||
smartContractErrors = lineaRollupContractErrors
|
smartContractErrors = lineaRollupContractErrors,
|
||||||
)
|
)
|
||||||
log.info("starting stack for recovery of state pushed to L1")
|
log.info("starting stack for recovery of state pushed to L1")
|
||||||
val staterecoveryNodesStartFuture = execCommandAndAssertSuccess(
|
val staterecoveryNodesStartFuture = execCommandAndAssertSuccess(
|
||||||
@@ -98,7 +98,7 @@ class StateRecoveryWithRealBesuAndStateManagerIntTest {
|
|||||||
"L1_ROLLUP_CONTRACT_ADDRESS=${rollupDeploymentResult.contractAddress} " +
|
"L1_ROLLUP_CONTRACT_ADDRESS=${rollupDeploymentResult.contractAddress} " +
|
||||||
"STATERECOVERY_OVERRIDE_START_BLOCK_NUMBER=1",
|
"STATERECOVERY_OVERRIDE_START_BLOCK_NUMBER=1",
|
||||||
timeout = 1.minutes,
|
timeout = 1.minutes,
|
||||||
log = log
|
log = log,
|
||||||
).thenPeek {
|
).thenPeek {
|
||||||
log.info("make staterecovery-replay-from-block executed")
|
log.info("make staterecovery-replay-from-block executed")
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ class StateRecoveryWithRealBesuAndStateManagerIntTest {
|
|||||||
blobChunksMaxSize = 9,
|
blobChunksMaxSize = 9,
|
||||||
l1Web3jClient = Web3jClientManager.l1Client,
|
l1Web3jClient = Web3jClientManager.l1Client,
|
||||||
waitTimeout = 4.minutes,
|
waitTimeout = 4.minutes,
|
||||||
log = log
|
log = log,
|
||||||
)
|
)
|
||||||
log.info("finalization={} executed on l1", lastAggregation.intervalString())
|
log.info("finalization={} executed on l1", lastAggregation.intervalString())
|
||||||
}
|
}
|
||||||
@@ -125,13 +125,13 @@ class StateRecoveryWithRealBesuAndStateManagerIntTest {
|
|||||||
|
|
||||||
assertBesuAndShomeiRecoveredAsExpected(
|
assertBesuAndShomeiRecoveredAsExpected(
|
||||||
lastAggregationAndBlobs,
|
lastAggregationAndBlobs,
|
||||||
timeout = 5.minutes
|
timeout = 5.minutes,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assertBesuAndShomeiRecoveredAsExpected(
|
private fun assertBesuAndShomeiRecoveredAsExpected(
|
||||||
targetAggregationAndBlobs: AggregationAndBlobs,
|
targetAggregationAndBlobs: AggregationAndBlobs,
|
||||||
timeout: Duration
|
timeout: Duration,
|
||||||
) {
|
) {
|
||||||
val targetAggregation = targetAggregationAndBlobs.aggregation!!
|
val targetAggregation = targetAggregationAndBlobs.aggregation!!
|
||||||
val expectedZkEndStateRootHash = targetAggregationAndBlobs.blobs.last().blobCompressionProof!!.finalStateRootHash
|
val expectedZkEndStateRootHash = targetAggregationAndBlobs.blobs.last().blobCompressionProof!!.finalStateRootHash
|
||||||
@@ -141,7 +141,7 @@ class StateRecoveryWithRealBesuAndStateManagerIntTest {
|
|||||||
stateManagerClient = stateManagerClient,
|
stateManagerClient = stateManagerClient,
|
||||||
targetAggregation.endBlockNumber,
|
targetAggregation.endBlockNumber,
|
||||||
expectedZkEndStateRootHash,
|
expectedZkEndStateRootHash,
|
||||||
timeout = timeout
|
timeout = timeout,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ class SubmissionsFetchingTaskIntTest {
|
|||||||
blobsResponsesDir = "$testDataDir/compression/responses",
|
blobsResponsesDir = "$testDataDir/compression/responses",
|
||||||
aggregationsResponsesDir = "$testDataDir/aggregation/responses",
|
aggregationsResponsesDir = "$testDataDir/aggregation/responses",
|
||||||
numberOfAggregations = 7,
|
numberOfAggregations = 7,
|
||||||
extraBlobsWithoutAggregation = 0
|
extraBlobsWithoutAggregation = 0,
|
||||||
)
|
)
|
||||||
val rollupDeploymentResult = ContractsManager.get()
|
val rollupDeploymentResult = ContractsManager.get()
|
||||||
.deployLineaRollup(numberOfOperators = 2, contractVersion = LineaContractVersion.V6).get()
|
.deployLineaRollup(numberOfOperators = 2, contractVersion = LineaContractVersion.V6).get()
|
||||||
@@ -77,14 +77,14 @@ class SubmissionsFetchingTaskIntTest {
|
|||||||
l1RpcEndpoint = URI(l1RpcUrl),
|
l1RpcEndpoint = URI(l1RpcUrl),
|
||||||
l1RequestRetryConfig = RetryConfig(backoffDelay = 2.seconds),
|
l1RequestRetryConfig = RetryConfig(backoffDelay = 2.seconds),
|
||||||
blobScanEndpoint = URI(blobScanUrl),
|
blobScanEndpoint = URI(blobScanUrl),
|
||||||
stateManagerClientEndpoint = URI("http://it-does-not-matter:5432")
|
stateManagerClientEndpoint = URI("http://it-does-not-matter:5432"),
|
||||||
)
|
)
|
||||||
|
|
||||||
contractClientForBlobSubmissions = rollupDeploymentResult.rollupOperatorClient
|
contractClientForBlobSubmissions = rollupDeploymentResult.rollupOperatorClient
|
||||||
contractClientForAggregationSubmissions = connectToLineaRollupContract(
|
contractClientForAggregationSubmissions = connectToLineaRollupContract(
|
||||||
rollupDeploymentResult.contractAddress,
|
rollupDeploymentResult.contractAddress,
|
||||||
rollupDeploymentResult.rollupOperators[1].txManager,
|
rollupDeploymentResult.rollupOperators[1].txManager,
|
||||||
smartContractErrors = lineaRollupContractErrors
|
smartContractErrors = lineaRollupContractErrors,
|
||||||
)
|
)
|
||||||
configureLoggers(
|
configureLoggers(
|
||||||
rootLevel = Level.INFO,
|
rootLevel = Level.INFO,
|
||||||
@@ -95,7 +95,7 @@ class SubmissionsFetchingTaskIntTest {
|
|||||||
"linea.plugin.staterecovery.clients" to Level.DEBUG,
|
"linea.plugin.staterecovery.clients" to Level.DEBUG,
|
||||||
"test.clients.l1.web3j-default" to Level.INFO,
|
"test.clients.l1.web3j-default" to Level.INFO,
|
||||||
"test.clients.l1.web3j.receipt-poller" 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()
|
submitDataToL1ContactAndWaitExecution()
|
||||||
}
|
}
|
||||||
@@ -103,18 +103,18 @@ class SubmissionsFetchingTaskIntTest {
|
|||||||
fun createFetcherTask(
|
fun createFetcherTask(
|
||||||
l2StartBlockNumber: ULong,
|
l2StartBlockNumber: ULong,
|
||||||
debugForceSyncStopBlockNumber: ULong? = null,
|
debugForceSyncStopBlockNumber: ULong? = null,
|
||||||
queuesSizeLimit: Int = 2
|
queuesSizeLimit: Int = 2,
|
||||||
): SubmissionsFetchingTask {
|
): SubmissionsFetchingTask {
|
||||||
val l1EventsClient = LineaSubmissionEventsClientImpl(
|
val l1EventsClient = LineaSubmissionEventsClientImpl(
|
||||||
logsSearcher = appClients.ethLogsSearcher,
|
logsSearcher = appClients.ethLogsSearcher,
|
||||||
smartContractAddress = appClients.lineaContractClient.contractAddress,
|
smartContractAddress = appClients.lineaContractClient.contractAddress,
|
||||||
l1LatestSearchBlock = BlockParameter.Tag.LATEST,
|
l1LatestSearchBlock = BlockParameter.Tag.LATEST,
|
||||||
logsBlockChunkSize = 5000
|
logsBlockChunkSize = 5000,
|
||||||
)
|
)
|
||||||
val blobDecompressor: BlobDecompressorAndDeserializer = BlobDecompressorToDomainV1(
|
val blobDecompressor: BlobDecompressorAndDeserializer = BlobDecompressorToDomainV1(
|
||||||
decompressor = GoNativeBlobDecompressorFactory.getInstance(BlobDecompressorVersion.V1_2_0),
|
decompressor = GoNativeBlobDecompressorFactory.getInstance(BlobDecompressorVersion.V1_2_0),
|
||||||
staticFields = BlockHeaderStaticFields.localDev,
|
staticFields = BlockHeaderStaticFields.localDev,
|
||||||
vertx = vertx
|
vertx = vertx,
|
||||||
)
|
)
|
||||||
|
|
||||||
return SubmissionsFetchingTask(
|
return SubmissionsFetchingTask(
|
||||||
@@ -129,14 +129,14 @@ class SubmissionsFetchingTaskIntTest {
|
|||||||
submissionEventsQueueLimit = queuesSizeLimit,
|
submissionEventsQueueLimit = queuesSizeLimit,
|
||||||
compressedBlobsQueueLimit = queuesSizeLimit,
|
compressedBlobsQueueLimit = queuesSizeLimit,
|
||||||
targetDecompressedBlobsQueueLimit = queuesSizeLimit,
|
targetDecompressedBlobsQueueLimit = queuesSizeLimit,
|
||||||
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber
|
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun submitDataToL1ContactAndWaitExecution(
|
private fun submitDataToL1ContactAndWaitExecution(
|
||||||
aggregationsAndBlobs: List<AggregationAndBlobs> = this.aggregationsAndBlobs,
|
aggregationsAndBlobs: List<AggregationAndBlobs> = this.aggregationsAndBlobs,
|
||||||
blobChunksSize: Int = 9,
|
blobChunksSize: Int = 9,
|
||||||
waitTimeout: Duration = 4.minutes
|
waitTimeout: Duration = 4.minutes,
|
||||||
) {
|
) {
|
||||||
submitBlobsAndAggregationsAndWaitExecution(
|
submitBlobsAndAggregationsAndWaitExecution(
|
||||||
contractClientForBlobSubmission = contractClientForBlobSubmissions,
|
contractClientForBlobSubmission = contractClientForBlobSubmissions,
|
||||||
@@ -146,9 +146,9 @@ class SubmissionsFetchingTaskIntTest {
|
|||||||
waitTimeout = waitTimeout,
|
waitTimeout = waitTimeout,
|
||||||
l1Web3jClient = createWeb3jHttpClient(
|
l1Web3jClient = createWeb3jHttpClient(
|
||||||
rpcUrl = l1RpcUrl,
|
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(
|
assertSubmissionsAreCorrectlyFetched(
|
||||||
l2StartBlockNumber = 1UL,
|
l2StartBlockNumber = 1UL,
|
||||||
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber
|
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assertSubmissionsAreCorrectlyFetched(
|
private fun assertSubmissionsAreCorrectlyFetched(
|
||||||
l2StartBlockNumber: ULong,
|
l2StartBlockNumber: ULong,
|
||||||
debugForceSyncStopBlockNumber: ULong? = null
|
debugForceSyncStopBlockNumber: ULong? = null,
|
||||||
) {
|
) {
|
||||||
val submissionsFetcher = createFetcherTask(
|
val submissionsFetcher = createFetcherTask(
|
||||||
l2StartBlockNumber = l2StartBlockNumber,
|
l2StartBlockNumber = l2StartBlockNumber,
|
||||||
queuesSizeLimit = 2
|
queuesSizeLimit = 2,
|
||||||
)
|
)
|
||||||
.also { it.start() }
|
.also { it.start() }
|
||||||
val expectedAggregationsAndBlobsToBeFetched =
|
val expectedAggregationsAndBlobsToBeFetched =
|
||||||
@@ -208,7 +208,7 @@ class SubmissionsFetchingTaskIntTest {
|
|||||||
?.also { nextSubmission ->
|
?.also { nextSubmission ->
|
||||||
fetchedSubmissions.add(nextSubmission)
|
fetchedSubmissions.add(nextSubmission)
|
||||||
submissionsFetcher.pruneQueueForElementsUpToInclusive(
|
submissionsFetcher.pruneQueueForElementsUpToInclusive(
|
||||||
elHeadBlockNumber = nextSubmission.submissionEvents.dataFinalizedEvent.event.endBlockNumber
|
elHeadBlockNumber = nextSubmission.submissionEvents.dataFinalizedEvent.event.endBlockNumber,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
assertThat(submissionsFetcher.finalizationsReadyToImport()).isLessThanOrEqualTo(2)
|
assertThat(submissionsFetcher.finalizationsReadyToImport()).isLessThanOrEqualTo(2)
|
||||||
@@ -241,11 +241,11 @@ class SubmissionsFetchingTaskIntTest {
|
|||||||
|
|
||||||
fun assertFetchedData(
|
fun assertFetchedData(
|
||||||
fetchedData: SubmissionEventsAndData<BlockFromL1RecoveredData>,
|
fetchedData: SubmissionEventsAndData<BlockFromL1RecoveredData>,
|
||||||
sotAggregationData: AggregationAndBlobs
|
sotAggregationData: AggregationAndBlobs,
|
||||||
) {
|
) {
|
||||||
assertEventMatchesAggregation(
|
assertEventMatchesAggregation(
|
||||||
fetchedData.submissionEvents.dataFinalizedEvent.event,
|
fetchedData.submissionEvents.dataFinalizedEvent.event,
|
||||||
sotAggregationData.aggregation!!
|
sotAggregationData.aggregation!!,
|
||||||
)
|
)
|
||||||
assertThat(fetchedData.data.first().header.blockNumber)
|
assertThat(fetchedData.data.first().header.blockNumber)
|
||||||
.isEqualTo(sotAggregationData.blobs.first().startBlockNumber)
|
.isEqualTo(sotAggregationData.blobs.first().startBlockNumber)
|
||||||
@@ -255,7 +255,7 @@ class SubmissionsFetchingTaskIntTest {
|
|||||||
|
|
||||||
fun assertEventMatchesAggregation(
|
fun assertEventMatchesAggregation(
|
||||||
event: DataFinalizedV3,
|
event: DataFinalizedV3,
|
||||||
aggregation: Aggregation
|
aggregation: Aggregation,
|
||||||
) {
|
) {
|
||||||
assertThat(event.startBlockNumber).isEqualTo(aggregation.startBlockNumber)
|
assertThat(event.startBlockNumber).isEqualTo(aggregation.startBlockNumber)
|
||||||
assertThat(event.endBlockNumber).isEqualTo(aggregation.endBlockNumber)
|
assertThat(event.endBlockNumber).isEqualTo(aggregation.endBlockNumber)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import tech.pegasys.teku.infrastructure.async.SafeFuture
|
|||||||
class FakeExecutionLayerClient(
|
class FakeExecutionLayerClient(
|
||||||
headBlock: BlockNumberAndHash = BlockNumberAndHash(number = 0uL, hash = ByteArray(32) { 0 }),
|
headBlock: BlockNumberAndHash = BlockNumberAndHash(number = 0uL, hash = ByteArray(32) { 0 }),
|
||||||
initialStateRecoverStartBlockNumber: ULong? = null,
|
initialStateRecoverStartBlockNumber: ULong? = null,
|
||||||
loggerName: String? = null
|
loggerName: String? = null,
|
||||||
) : ExecutionLayerClient {
|
) : ExecutionLayerClient {
|
||||||
private val log = loggerName
|
private val log = loggerName
|
||||||
?.let { LogManager.getLogger(loggerName) }
|
?.let { LogManager.getLogger(loggerName) }
|
||||||
@@ -35,7 +35,7 @@ class FakeExecutionLayerClient(
|
|||||||
val stateRecoverStatus: StateRecoveryStatus
|
val stateRecoverStatus: StateRecoveryStatus
|
||||||
get() = StateRecoveryStatus(
|
get() = StateRecoveryStatus(
|
||||||
headBlockNumber = headBlock.number,
|
headBlockNumber = headBlock.number,
|
||||||
stateRecoverStartBlockNumber = stateRecoverStartBlockNumber
|
stateRecoverStartBlockNumber = stateRecoverStartBlockNumber,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
@@ -46,14 +46,14 @@ class FakeExecutionLayerClient(
|
|||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun lineaEngineImportBlocksFromBlob(
|
override fun lineaEngineImportBlocksFromBlob(
|
||||||
blocks: List<BlockFromL1RecoveredData>
|
blocks: List<BlockFromL1RecoveredData>,
|
||||||
): SafeFuture<Unit> {
|
): SafeFuture<Unit> {
|
||||||
if (log.isTraceEnabled) {
|
if (log.isTraceEnabled) {
|
||||||
log.trace("lineaEngineImportBlocksFromBlob($blocks)")
|
log.trace("lineaEngineImportBlocksFromBlob($blocks)")
|
||||||
} else {
|
} else {
|
||||||
val interval = CommonDomainFunctions.blockIntervalString(
|
val interval = CommonDomainFunctions.blockIntervalString(
|
||||||
blocks.first().header.blockNumber,
|
blocks.first().header.blockNumber,
|
||||||
blocks.last().header.blockNumber
|
blocks.last().header.blockNumber,
|
||||||
)
|
)
|
||||||
log.debug("lineaEngineImportBlocksFromBlob(interval=$interval)")
|
log.debug("lineaEngineImportBlocksFromBlob(interval=$interval)")
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ class FakeExecutionLayerClient(
|
|||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun getBlockNumberAndHash(
|
override fun getBlockNumberAndHash(
|
||||||
blockParameter: BlockParameter
|
blockParameter: BlockParameter,
|
||||||
): SafeFuture<BlockNumberAndHash> {
|
): SafeFuture<BlockNumberAndHash> {
|
||||||
log.trace("getBlockNumberAndHash($blockParameter): $headBlock")
|
log.trace("getBlockNumberAndHash($blockParameter): $headBlock")
|
||||||
return SafeFuture.completedFuture(headBlock)
|
return SafeFuture.completedFuture(headBlock)
|
||||||
@@ -78,7 +78,7 @@ class FakeExecutionLayerClient(
|
|||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun lineaEnableStateRecovery(
|
override fun lineaEnableStateRecovery(
|
||||||
stateRecoverStartBlockNumber: ULong
|
stateRecoverStartBlockNumber: ULong,
|
||||||
): SafeFuture<StateRecoveryStatus> {
|
): SafeFuture<StateRecoveryStatus> {
|
||||||
this.stateRecoverStartBlockNumber = stateRecoverStartBlockNumber
|
this.stateRecoverStartBlockNumber = stateRecoverStartBlockNumber
|
||||||
log.debug("lineaEnableStateRecovery($stateRecoverStartBlockNumber) = $stateRecoverStatus")
|
log.debug("lineaEnableStateRecovery($stateRecoverStartBlockNumber) = $stateRecoverStatus")
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import java.util.concurrent.ConcurrentHashMap
|
|||||||
|
|
||||||
open class FakeStateManagerClient(
|
open class FakeStateManagerClient(
|
||||||
_blocksStateRootHashes: Map<ULong, ByteArray> = emptyMap(),
|
_blocksStateRootHashes: Map<ULong, ByteArray> = emptyMap(),
|
||||||
var headBlockNumber: ULong = _blocksStateRootHashes.keys.maxOrNull() ?: 0UL
|
var headBlockNumber: ULong = _blocksStateRootHashes.keys.maxOrNull() ?: 0UL,
|
||||||
) : StateManagerClientV1 {
|
) : StateManagerClientV1 {
|
||||||
open val blocksStateRootHashes: MutableMap<ULong, ByteArray> =
|
open val blocksStateRootHashes: MutableMap<ULong, ByteArray> =
|
||||||
ConcurrentHashMap<ULong, ByteArray>(_blocksStateRootHashes)
|
ConcurrentHashMap<ULong, ByteArray>(_blocksStateRootHashes)
|
||||||
@@ -33,8 +33,8 @@ open class FakeStateManagerClient(
|
|||||||
?.let { SafeFuture.completedFuture(it) }
|
?.let { SafeFuture.completedFuture(it) }
|
||||||
?: SafeFuture.failedFuture(
|
?: SafeFuture.failedFuture(
|
||||||
RuntimeException(
|
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(
|
override fun rollupGetStateMerkleProofWithTypedError(
|
||||||
blockInterval: BlockInterval
|
blockInterval: BlockInterval,
|
||||||
): SafeFuture<Result<GetZkEVMStateMerkleProofResponse, ErrorResponse<StateManagerErrorType>>> {
|
): SafeFuture<Result<GetZkEVMStateMerkleProofResponse, ErrorResponse<StateManagerErrorType>>> {
|
||||||
// For state recovery, we just need the endStateRootHash
|
// For state recovery, we just need the endStateRootHash
|
||||||
return getStateRootHash(blockInterval.endBlockNumber)
|
return getStateRootHash(blockInterval.endBlockNumber)
|
||||||
@@ -53,26 +53,26 @@ open class FakeStateManagerClient(
|
|||||||
zkStateMerkleProof = ArrayNode(null),
|
zkStateMerkleProof = ArrayNode(null),
|
||||||
zkParentStateRootHash = ByteArray(32),
|
zkParentStateRootHash = ByteArray(32),
|
||||||
zkEndStateRootHash = stateRootHash,
|
zkEndStateRootHash = stateRootHash,
|
||||||
zkStateManagerVersion = "fake-version"
|
zkStateManagerVersion = "fake-version",
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FakeStateManagerClientBasedOnBlobsRecords(
|
class FakeStateManagerClientBasedOnBlobsRecords(
|
||||||
val blobRecords: List<BlobRecord>
|
val blobRecords: List<BlobRecord>,
|
||||||
) : FakeStateManagerClient(
|
) : FakeStateManagerClient(
|
||||||
_blocksStateRootHashes = blobRecords
|
_blocksStateRootHashes = blobRecords
|
||||||
.associate { it.endBlockNumber to it.blobCompressionProof!!.finalStateRootHash }
|
.associate { it.endBlockNumber to it.blobCompressionProof!!.finalStateRootHash },
|
||||||
)
|
)
|
||||||
|
|
||||||
class FakeStateManagerClientReadFromL1(
|
class FakeStateManagerClientReadFromL1(
|
||||||
headBlockNumber: ULong,
|
headBlockNumber: ULong,
|
||||||
val logsSearcher: EthLogsSearcher,
|
val logsSearcher: EthLogsSearcher,
|
||||||
val contractAddress: String
|
val contractAddress: String,
|
||||||
) : FakeStateManagerClient(
|
) : FakeStateManagerClient(
|
||||||
headBlockNumber = headBlockNumber
|
headBlockNumber = headBlockNumber,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
override fun getStateRootHash(blockNumber: ULong): SafeFuture<ByteArray> {
|
override fun getStateRootHash(blockNumber: ULong): SafeFuture<ByteArray> {
|
||||||
@@ -87,8 +87,8 @@ class FakeStateManagerClientReadFromL1(
|
|||||||
topics = listOf(
|
topics = listOf(
|
||||||
DataFinalizedV3.topic,
|
DataFinalizedV3.topic,
|
||||||
null,
|
null,
|
||||||
blockNumber.toHexStringUInt256()
|
blockNumber.toHexStringUInt256(),
|
||||||
)
|
),
|
||||||
).thenApply { logs ->
|
).thenApply { logs ->
|
||||||
logs.firstOrNull()?.let { finalizationLog ->
|
logs.firstOrNull()?.let { finalizationLog ->
|
||||||
DataFinalizedV3.fromEthLog(finalizationLog).event.finalStateRootHash
|
DataFinalizedV3.fromEthLog(finalizationLog).event.finalStateRootHash
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ open class TestRunner(
|
|||||||
private val l1RpcUrl: String,
|
private val l1RpcUrl: String,
|
||||||
private val blobScanUrl: String,
|
private val blobScanUrl: String,
|
||||||
private val blobScanRatelimitBackoffDelay: Duration? = 1.seconds,
|
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")
|
private val log = LogManager.getLogger("test.case.TestRunner")
|
||||||
val appConfig = StateRecoveryApp.Config(
|
val appConfig = StateRecoveryApp.Config(
|
||||||
@@ -45,7 +45,7 @@ open class TestRunner(
|
|||||||
executionClientPollingInterval = 1.seconds,
|
executionClientPollingInterval = 1.seconds,
|
||||||
smartContractAddress = smartContractAddress,
|
smartContractAddress = smartContractAddress,
|
||||||
l1getLogsChunkSize = 10_000u,
|
l1getLogsChunkSize = 10_000u,
|
||||||
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber
|
debugForceSyncStopBlockNumber = debugForceSyncStopBlockNumber,
|
||||||
)
|
)
|
||||||
val appClients = createAppClients(
|
val appClients = createAppClients(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
@@ -56,17 +56,17 @@ open class TestRunner(
|
|||||||
blobScanEndpoint = URI(blobScanUrl),
|
blobScanEndpoint = URI(blobScanUrl),
|
||||||
blobScanRequestRetryConfig = RetryConfig(backoffDelay = 10.milliseconds, timeout = 2.minutes),
|
blobScanRequestRetryConfig = RetryConfig(backoffDelay = 10.milliseconds, timeout = 2.minutes),
|
||||||
blobscanRequestRateLimitBackoffDelay = blobScanRatelimitBackoffDelay,
|
blobscanRequestRateLimitBackoffDelay = blobScanRatelimitBackoffDelay,
|
||||||
stateManagerClientEndpoint = URI("http://it-does-not-matter:5432")
|
stateManagerClientEndpoint = URI("http://it-does-not-matter:5432"),
|
||||||
)
|
)
|
||||||
private val fakeExecutionLayerClient = FakeExecutionLayerClient(
|
private val fakeExecutionLayerClient = FakeExecutionLayerClient(
|
||||||
headBlock = BlockNumberAndHash(number = l2RecoveryStartBlockNumber - 1UL, hash = ByteArray(32) { 0 }),
|
headBlock = BlockNumberAndHash(number = l2RecoveryStartBlockNumber - 1UL, hash = ByteArray(32) { 0 }),
|
||||||
initialStateRecoverStartBlockNumber = l2RecoveryStartBlockNumber,
|
initialStateRecoverStartBlockNumber = l2RecoveryStartBlockNumber,
|
||||||
loggerName = "test.fake.clients.execution-layer"
|
loggerName = "test.fake.clients.execution-layer",
|
||||||
)
|
)
|
||||||
var fakeStateManagerClient: StateManagerClientV1 = FakeStateManagerClientReadFromL1(
|
var fakeStateManagerClient: StateManagerClientV1 = FakeStateManagerClientReadFromL1(
|
||||||
headBlockNumber = ULong.MAX_VALUE,
|
headBlockNumber = ULong.MAX_VALUE,
|
||||||
logsSearcher = appClients.ethLogsSearcher,
|
logsSearcher = appClients.ethLogsSearcher,
|
||||||
contractAddress = StateRecoveryApp.Config.lineaSepolia.smartContractAddress
|
contractAddress = StateRecoveryApp.Config.lineaSepolia.smartContractAddress,
|
||||||
)
|
)
|
||||||
var stateRecoverApp: StateRecoveryApp = StateRecoveryApp(
|
var stateRecoverApp: StateRecoveryApp = StateRecoveryApp(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
@@ -77,7 +77,7 @@ open class TestRunner(
|
|||||||
transactionDetailsClient = appClients.transactionDetailsClient,
|
transactionDetailsClient = appClients.transactionDetailsClient,
|
||||||
blockHeaderStaticFields = BlockHeaderStaticFields.localDev,
|
blockHeaderStaticFields = BlockHeaderStaticFields.localDev,
|
||||||
lineaContractClient = appClients.lineaContractClient,
|
lineaContractClient = appClients.lineaContractClient,
|
||||||
config = appConfig
|
config = appConfig,
|
||||||
)
|
)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -86,12 +86,12 @@ open class TestRunner(
|
|||||||
"linea.staterecovery" to Level.TRACE,
|
"linea.staterecovery" to Level.TRACE,
|
||||||
"linea.plugin.staterecovery" to Level.INFO,
|
"linea.plugin.staterecovery" to Level.INFO,
|
||||||
"linea.plugin.staterecovery.clients.l1.blob-scan" to Level.TRACE,
|
"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(
|
fun run(
|
||||||
timeout: kotlin.time.Duration = 10.minutes
|
timeout: kotlin.time.Duration = 10.minutes,
|
||||||
) {
|
) {
|
||||||
log.info("Running test case")
|
log.info("Running test case")
|
||||||
stateRecoverApp.start().get()
|
stateRecoverApp.start().get()
|
||||||
@@ -113,7 +113,7 @@ fun main() {
|
|||||||
l2RecoveryStartBlockNumber = 18_504_528UL,
|
l2RecoveryStartBlockNumber = 18_504_528UL,
|
||||||
l1RpcUrl = "https://mainnet.infura.io/v3/$infuraAppKey",
|
l1RpcUrl = "https://mainnet.infura.io/v3/$infuraAppKey",
|
||||||
blobScanUrl = "https://api.blobscan.com/",
|
blobScanUrl = "https://api.blobscan.com/",
|
||||||
blobScanRatelimitBackoffDelay = 1.seconds
|
blobScanRatelimitBackoffDelay = 1.seconds,
|
||||||
)
|
)
|
||||||
// val sepoliaTestRunner = TestRunner(
|
// val sepoliaTestRunner = TestRunner(
|
||||||
// l1RpcUrl = "https://sepolia.infura.io/v3/$infuraAppKey",
|
// l1RpcUrl = "https://sepolia.infura.io/v3/$infuraAppKey",
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import kotlin.time.toJavaDuration
|
|||||||
fun execCommandAndAssertSuccess(
|
fun execCommandAndAssertSuccess(
|
||||||
command: String,
|
command: String,
|
||||||
timeout: Duration = 1.minutes,
|
timeout: Duration = 1.minutes,
|
||||||
log: Logger
|
log: Logger,
|
||||||
): SafeFuture<CommandResult> {
|
): SafeFuture<CommandResult> {
|
||||||
return Runner
|
return Runner
|
||||||
.executeCommandFailOnNonZeroExitCode(command, timeout = timeout, log = log)
|
.executeCommandFailOnNonZeroExitCode(command, timeout = timeout, log = log)
|
||||||
@@ -35,7 +35,7 @@ fun assertBesuAndShomeiRecoveredAsExpected(
|
|||||||
stateManagerClient: StateManagerClientV1,
|
stateManagerClient: StateManagerClientV1,
|
||||||
expectedBlockNumber: ULong,
|
expectedBlockNumber: ULong,
|
||||||
expectedZkEndStateRootHash: ByteArray,
|
expectedZkEndStateRootHash: ByteArray,
|
||||||
timeout: Duration = 60.seconds
|
timeout: Duration = 60.seconds,
|
||||||
) {
|
) {
|
||||||
await()
|
await()
|
||||||
.pollInterval(1.seconds.toJavaDuration())
|
.pollInterval(1.seconds.toJavaDuration())
|
||||||
@@ -53,7 +53,7 @@ fun waitExecutionLayerToBeUpAndRunning(
|
|||||||
executionLayerUrl: String,
|
executionLayerUrl: String,
|
||||||
expectedHeadBlockNumber: ULong = 0UL,
|
expectedHeadBlockNumber: ULong = 0UL,
|
||||||
log: Logger,
|
log: Logger,
|
||||||
timeout: Duration = 2.minutes
|
timeout: Duration = 2.minutes,
|
||||||
) {
|
) {
|
||||||
val web3jElClient = createWeb3jHttpClient(executionLayerUrl)
|
val web3jElClient = createWeb3jHttpClient(executionLayerUrl)
|
||||||
await()
|
await()
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import linea.staterecovery.DataFinalizedV3
|
|||||||
|
|
||||||
fun getLastFinalizationOnL1(
|
fun getLastFinalizationOnL1(
|
||||||
logsSearcher: EthLogsSearcherImpl,
|
logsSearcher: EthLogsSearcherImpl,
|
||||||
contractAddress: String
|
contractAddress: String,
|
||||||
): EthLogEvent<DataFinalizedV3> {
|
): EthLogEvent<DataFinalizedV3> {
|
||||||
return getFinalizationsOnL1(logsSearcher, contractAddress)
|
return getFinalizationsOnL1(logsSearcher, contractAddress)
|
||||||
.lastOrNull()
|
.lastOrNull()
|
||||||
@@ -16,12 +16,12 @@ fun getLastFinalizationOnL1(
|
|||||||
|
|
||||||
fun getFinalizationsOnL1(
|
fun getFinalizationsOnL1(
|
||||||
logsSearcher: EthLogsSearcherImpl,
|
logsSearcher: EthLogsSearcherImpl,
|
||||||
contractAddress: String
|
contractAddress: String,
|
||||||
): List<EthLogEvent<DataFinalizedV3>> {
|
): List<EthLogEvent<DataFinalizedV3>> {
|
||||||
return logsSearcher.getLogs(
|
return logsSearcher.getLogs(
|
||||||
fromBlock = BlockParameter.Tag.EARLIEST,
|
fromBlock = BlockParameter.Tag.EARLIEST,
|
||||||
toBlock = BlockParameter.Tag.LATEST,
|
toBlock = BlockParameter.Tag.LATEST,
|
||||||
address = contractAddress,
|
address = contractAddress,
|
||||||
topics = listOf(DataFinalizedV3.topic)
|
topics = listOf(DataFinalizedV3.topic),
|
||||||
).get().map(DataFinalizedV3.Companion::fromEthLog)
|
).get().map(DataFinalizedV3.Companion::fromEthLog)
|
||||||
}
|
}
|
||||||
|
|||||||
17
build.gradle
17
build.gradle
@@ -118,18 +118,13 @@ allprojects {
|
|||||||
indentWithSpaces(2)
|
indentWithSpaces(2)
|
||||||
endWithNewline()
|
endWithNewline()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// TODO in later ticket - apply these linting rules to all monorepo projects
|
java {
|
||||||
if (subproject.path.startsWith(':besu-plugins:linea-sequencer')) {
|
target 'src/**/*.java'
|
||||||
subproject.spotless {
|
targetExclude '**/src/test/java/**ReferenceTest**', '**/src/main/generated/**', '**/src/test/generated/**', '**/src/jmh/generated/**'
|
||||||
java {
|
removeUnusedImports()
|
||||||
target 'src/**/*.java'
|
trimTrailingWhitespace()
|
||||||
targetExclude '**/src/test/java/**ReferenceTest**', '**/src/main/generated/**', '**/src/test/generated/**', '**/src/jmh/generated/**'
|
endWithNewline()
|
||||||
removeUnusedImports()
|
|
||||||
trimTrailingWhitespace()
|
|
||||||
endWithNewline()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import org.apache.logging.log4j.Logger
|
|||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
inline fun <reified T : Any> loadConfigsOrError(
|
inline fun <reified T : Any> loadConfigsOrError(
|
||||||
configFiles: List<Path>
|
configFiles: List<Path>,
|
||||||
): Result<T, String> {
|
): Result<T, String> {
|
||||||
val confBuilder: ConfigLoaderBuilder = ConfigLoaderBuilder.Companion
|
val confBuilder: ConfigLoaderBuilder = ConfigLoaderBuilder.Companion
|
||||||
.empty()
|
.empty()
|
||||||
@@ -43,7 +43,7 @@ fun logErrorIfPresent(
|
|||||||
configName: String,
|
configName: String,
|
||||||
configFiles: List<Path>,
|
configFiles: List<Path>,
|
||||||
configLoadingResult: Result<Any?, String>,
|
configLoadingResult: Result<Any?, String>,
|
||||||
logger: Logger
|
logger: Logger,
|
||||||
) {
|
) {
|
||||||
if (configLoadingResult is Err) {
|
if (configLoadingResult is Err) {
|
||||||
logger.error("Failed to load $configName from files=$configFiles with error=${configLoadingResult.error}")
|
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(
|
inline fun <reified T : Any> loadConfigsAndLogErrors(
|
||||||
configFiles: List<Path>,
|
configFiles: List<Path>,
|
||||||
configName: String,
|
configName: String,
|
||||||
logger: Logger = LogManager.getLogger("linea.coordinator.config")
|
logger: Logger = LogManager.getLogger("linea.coordinator.config"),
|
||||||
): Result<T, String> {
|
): Result<T, String> {
|
||||||
return loadConfigsOrError<T>(configFiles)
|
return loadConfigsOrError<T>(configFiles)
|
||||||
.also { logErrorIfPresent(configName, configFiles, it, logger) }
|
.also { logErrorIfPresent(configName, configFiles, it, logger) }
|
||||||
@@ -64,7 +64,7 @@ fun loadConfigsOrError(
|
|||||||
tracesLimitsFileV2: Path,
|
tracesLimitsFileV2: Path,
|
||||||
gasPriceCapTimeOfDayMultipliersFile: Path,
|
gasPriceCapTimeOfDayMultipliersFile: Path,
|
||||||
smartContractErrorsFile: Path,
|
smartContractErrorsFile: Path,
|
||||||
logger: Logger = LogManager.getLogger("linea.coordinator.config")
|
logger: Logger = LogManager.getLogger("linea.coordinator.config"),
|
||||||
): Result<CoordinatorConfigTomlDto, String> {
|
): Result<CoordinatorConfigTomlDto, String> {
|
||||||
val coordinatorBaseConfigs =
|
val coordinatorBaseConfigs =
|
||||||
loadConfigsAndLogErrors<CoordinatorConfigTomlDto>(coordinatorConfigFiles, "coordinator", logger)
|
loadConfigsAndLogErrors<CoordinatorConfigTomlDto>(coordinatorConfigFiles, "coordinator", logger)
|
||||||
@@ -74,18 +74,18 @@ fun loadConfigsOrError(
|
|||||||
loadConfigsAndLogErrors<GasPriceCapTimeOfDayMultipliersConfig>(
|
loadConfigsAndLogErrors<GasPriceCapTimeOfDayMultipliersConfig>(
|
||||||
listOf(gasPriceCapTimeOfDayMultipliersFile),
|
listOf(gasPriceCapTimeOfDayMultipliersFile),
|
||||||
"l1 submission gas prices caps",
|
"l1 submission gas prices caps",
|
||||||
logger
|
logger,
|
||||||
)
|
)
|
||||||
val smartContractErrorsConfig = loadConfigsAndLogErrors<SmartContractErrorCodesConfig>(
|
val smartContractErrorsConfig = loadConfigsAndLogErrors<SmartContractErrorCodesConfig>(
|
||||||
listOf(smartContractErrorsFile),
|
listOf(smartContractErrorsFile),
|
||||||
"smart contract errors",
|
"smart contract errors",
|
||||||
logger
|
logger,
|
||||||
)
|
)
|
||||||
val configError = listOf(
|
val configError = listOf(
|
||||||
coordinatorBaseConfigs,
|
coordinatorBaseConfigs,
|
||||||
tracesLimitsV2Configs,
|
tracesLimitsV2Configs,
|
||||||
gasPriceCapTimeOfDayMultipliersConfig,
|
gasPriceCapTimeOfDayMultipliersConfig,
|
||||||
smartContractErrorsConfig
|
smartContractErrorsConfig,
|
||||||
)
|
)
|
||||||
.find { it is Err }
|
.find { it is Err }
|
||||||
|
|
||||||
@@ -98,13 +98,13 @@ fun loadConfigsOrError(
|
|||||||
val finalConfig = baseConfig.copy(
|
val finalConfig = baseConfig.copy(
|
||||||
conflation = baseConfig.conflation.copy(
|
conflation = baseConfig.conflation.copy(
|
||||||
_tracesLimitsV2 = tracesLimitsV2Configs.get()?.tracesLimits?.let { TracesCountersV2(it) },
|
_tracesLimitsV2 = tracesLimitsV2Configs.get()?.tracesLimits?.let { TracesCountersV2(it) },
|
||||||
_smartContractErrors = smartContractErrorsConfig.get()!!.smartContractErrors
|
_smartContractErrors = smartContractErrorsConfig.get()!!.smartContractErrors,
|
||||||
),
|
),
|
||||||
l1DynamicGasPriceCapService = baseConfig.l1DynamicGasPriceCapService.copy(
|
l1DynamicGasPriceCapService = baseConfig.l1DynamicGasPriceCapService.copy(
|
||||||
gasPriceCapCalculation = baseConfig.l1DynamicGasPriceCapService.gasPriceCapCalculation.copy(
|
gasPriceCapCalculation = baseConfig.l1DynamicGasPriceCapService.gasPriceCapCalculation.copy(
|
||||||
timeOfDayMultipliers = gasPriceCapTimeOfDayMultipliersConfig.get()?.gasPriceCapTimeOfDayMultipliers
|
timeOfDayMultipliers = gasPriceCapTimeOfDayMultipliersConfig.get()?.gasPriceCapTimeOfDayMultipliers,
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
return Ok(finalConfig)
|
return Ok(finalConfig)
|
||||||
}
|
}
|
||||||
@@ -114,14 +114,14 @@ fun loadConfigs(
|
|||||||
tracesLimitsFileV2: Path,
|
tracesLimitsFileV2: Path,
|
||||||
gasPriceCapTimeOfDayMultipliersFile: Path,
|
gasPriceCapTimeOfDayMultipliersFile: Path,
|
||||||
smartContractErrorsFile: Path,
|
smartContractErrorsFile: Path,
|
||||||
logger: Logger = LogManager.getLogger("linea.coordinator.config")
|
logger: Logger = LogManager.getLogger("linea.coordinator.config"),
|
||||||
): CoordinatorConfig {
|
): CoordinatorConfig {
|
||||||
loadConfigsOrError(
|
loadConfigsOrError(
|
||||||
coordinatorConfigFiles,
|
coordinatorConfigFiles,
|
||||||
tracesLimitsFileV2,
|
tracesLimitsFileV2,
|
||||||
gasPriceCapTimeOfDayMultipliersFile,
|
gasPriceCapTimeOfDayMultipliersFile,
|
||||||
smartContractErrorsFile,
|
smartContractErrorsFile,
|
||||||
logger
|
logger,
|
||||||
).let {
|
).let {
|
||||||
return it
|
return it
|
||||||
.getOrElse {
|
.getOrElse {
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import net.consensys.linea.vertx.ObservabilityServer
|
|||||||
|
|
||||||
class Api(
|
class Api(
|
||||||
private val configs: Config,
|
private val configs: Config,
|
||||||
private val vertx: Vertx
|
private val vertx: Vertx,
|
||||||
) {
|
) {
|
||||||
data class Config(
|
data class Config(
|
||||||
val observabilityPort: UInt
|
val observabilityPort: UInt,
|
||||||
)
|
)
|
||||||
|
|
||||||
private var observabilityServerId: String? = null
|
private var observabilityServerId: String? = null
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import java.net.URI
|
|||||||
fun createTransactionManager(
|
fun createTransactionManager(
|
||||||
vertx: Vertx,
|
vertx: Vertx,
|
||||||
signerConfig: SignerConfig,
|
signerConfig: SignerConfig,
|
||||||
client: Web3j
|
client: Web3j,
|
||||||
): AsyncFriendlyTransactionManager {
|
): AsyncFriendlyTransactionManager {
|
||||||
val transactionSignService = when (signerConfig.type) {
|
val transactionSignService = when (signerConfig.type) {
|
||||||
SignerConfig.Type.Web3j -> {
|
SignerConfig.Type.Web3j -> {
|
||||||
@@ -57,7 +57,7 @@ fun createLineaRollupContractClient(
|
|||||||
contractGasProvider: ContractGasProvider,
|
contractGasProvider: ContractGasProvider,
|
||||||
web3jClient: Web3j,
|
web3jClient: Web3j,
|
||||||
smartContractErrors: SmartContractErrors,
|
smartContractErrors: SmartContractErrors,
|
||||||
useEthEstimateGas: Boolean
|
useEthEstimateGas: Boolean,
|
||||||
): LineaRollupSmartContractClient {
|
): LineaRollupSmartContractClient {
|
||||||
return Web3JLineaRollupSmartContractClient.load(
|
return Web3JLineaRollupSmartContractClient.load(
|
||||||
contractAddress = l1Config.zkEvmContractAddress,
|
contractAddress = l1Config.zkEvmContractAddress,
|
||||||
@@ -65,6 +65,6 @@ fun createLineaRollupContractClient(
|
|||||||
transactionManager = transactionManager,
|
transactionManager = transactionManager,
|
||||||
contractGasProvider = contractGasProvider,
|
contractGasProvider = contractGasProvider,
|
||||||
smartContractErrors = smartContractErrors,
|
smartContractErrors = smartContractErrors,
|
||||||
useEthEstimateGas = useEthEstimateGas
|
useEthEstimateGas = useEthEstimateGas,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,20 +51,20 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
|
|||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
metricsFacade = MicrometerMetricsFacade(meterRegistry),
|
metricsFacade = MicrometerMetricsFacade(meterRegistry),
|
||||||
requestResponseLogLevel = Level.TRACE,
|
requestResponseLogLevel = Level.TRACE,
|
||||||
failuresLogLevel = Level.WARN
|
failuresLogLevel = Level.WARN,
|
||||||
)
|
)
|
||||||
private val api = Api(
|
private val api = Api(
|
||||||
Api.Config(
|
Api.Config(
|
||||||
configs.api.observabilityPort
|
configs.api.observabilityPort,
|
||||||
),
|
),
|
||||||
vertx
|
vertx,
|
||||||
)
|
)
|
||||||
private val l2Web3jClient: Web3j = createWeb3jHttpClient(
|
private val l2Web3jClient: Web3j = createWeb3jHttpClient(
|
||||||
rpcUrl = configs.l2.rpcEndpoint.toString(),
|
rpcUrl = configs.l2.rpcEndpoint.toString(),
|
||||||
log = LogManager.getLogger("clients.l2.eth-api.rpc-node"),
|
log = LogManager.getLogger("clients.l2.eth-api.rpc-node"),
|
||||||
pollingInterval = 1.seconds,
|
pollingInterval = 1.seconds,
|
||||||
requestResponseLogLevel = Level.TRACE,
|
requestResponseLogLevel = Level.TRACE,
|
||||||
failuresLogLevel = Level.DEBUG
|
failuresLogLevel = Level.DEBUG,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val persistenceRetryer = PersistenceRetryer(
|
private val persistenceRetryer = PersistenceRetryer(
|
||||||
@@ -72,8 +72,8 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
|
|||||||
config = PersistenceRetryer.Config(
|
config = PersistenceRetryer.Config(
|
||||||
backoffDelay = configs.persistenceRetry.backoffDelay.toKotlinDuration(),
|
backoffDelay = configs.persistenceRetry.backoffDelay.toKotlinDuration(),
|
||||||
maxRetries = configs.persistenceRetry.maxRetries,
|
maxRetries = configs.persistenceRetry.maxRetries,
|
||||||
timeout = configs.persistenceRetry.timeout?.toKotlinDuration()
|
timeout = configs.persistenceRetry.timeout?.toKotlinDuration(),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val sqlClient: SqlClient = initDb(configs.database)
|
private val sqlClient: SqlClient = initDb(configs.database)
|
||||||
@@ -81,10 +81,10 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
|
|||||||
PostgresBatchesRepository(
|
PostgresBatchesRepository(
|
||||||
batchesDao = RetryingBatchesPostgresDao(
|
batchesDao = RetryingBatchesPostgresDao(
|
||||||
delegate = BatchesPostgresDao(
|
delegate = BatchesPostgresDao(
|
||||||
connection = sqlClient
|
connection = sqlClient,
|
||||||
),
|
),
|
||||||
persistenceRetryer = persistenceRetryer
|
persistenceRetryer = persistenceRetryer,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val blobsRepository =
|
private val blobsRepository =
|
||||||
@@ -92,21 +92,21 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
|
|||||||
blobsDao = RetryingBlobsPostgresDao(
|
blobsDao = RetryingBlobsPostgresDao(
|
||||||
delegate = BlobsPostgresDao(
|
delegate = BlobsPostgresDao(
|
||||||
config = BlobsPostgresDao.Config(
|
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(
|
private val aggregationsRepository = AggregationsRepositoryImpl(
|
||||||
aggregationsPostgresDao = RetryingPostgresAggregationsDao(
|
aggregationsPostgresDao = RetryingPostgresAggregationsDao(
|
||||||
delegate = PostgresAggregationsDao(
|
delegate = PostgresAggregationsDao(
|
||||||
connection = sqlClient
|
connection = sqlClient,
|
||||||
),
|
),
|
||||||
persistenceRetryer = persistenceRetryer
|
persistenceRetryer = persistenceRetryer,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val l1FeeHistoriesRepository =
|
private val l1FeeHistoriesRepository =
|
||||||
@@ -116,11 +116,11 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
|
|||||||
minBaseFeePerBlobGasToCache =
|
minBaseFeePerBlobGasToCache =
|
||||||
configs.l1DynamicGasPriceCapService.gasPriceCapCalculation.historicBaseFeePerBlobGasLowerBound,
|
configs.l1DynamicGasPriceCapService.gasPriceCapCalculation.historicBaseFeePerBlobGasLowerBound,
|
||||||
fixedAverageRewardToCache =
|
fixedAverageRewardToCache =
|
||||||
configs.l1DynamicGasPriceCapService.gasPriceCapCalculation.historicAvgRewardConstant
|
configs.l1DynamicGasPriceCapService.gasPriceCapCalculation.historicAvgRewardConstant,
|
||||||
),
|
),
|
||||||
FeeHistoriesPostgresDao(
|
FeeHistoriesPostgresDao(
|
||||||
sqlClient
|
sqlClient,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val l1App = L1DependentApp(
|
private val l1App = L1DependentApp(
|
||||||
@@ -133,7 +133,7 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
|
|||||||
aggregationsRepository = aggregationsRepository,
|
aggregationsRepository = aggregationsRepository,
|
||||||
l1FeeHistoriesRepository = l1FeeHistoriesRepository,
|
l1FeeHistoriesRepository = l1FeeHistoriesRepository,
|
||||||
smartContractErrors = configs.conflation.smartContractErrors,
|
smartContractErrors = configs.conflation.smartContractErrors,
|
||||||
metricsFacade = micrometerMetricsFacade
|
metricsFacade = micrometerMetricsFacade,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val requestFileCleanup = DirectoryCleaner(
|
private val requestFileCleanup = DirectoryCleaner(
|
||||||
@@ -144,7 +144,7 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
|
|||||||
configs.proversConfig.proverA.proofAggregation.requestsDirectory,
|
configs.proversConfig.proverA.proofAggregation.requestsDirectory,
|
||||||
configs.proversConfig.proverB?.execution?.requestsDirectory,
|
configs.proversConfig.proverB?.execution?.requestsDirectory,
|
||||||
configs.proversConfig.proverB?.blobCompression?.requestsDirectory,
|
configs.proversConfig.proverB?.blobCompression?.requestsDirectory,
|
||||||
configs.proversConfig.proverB?.proofAggregation?.requestsDirectory
|
configs.proversConfig.proverB?.proofAggregation?.requestsDirectory,
|
||||||
),
|
),
|
||||||
fileFilters = DirectoryCleaner.getSuffixFileFilters(
|
fileFilters = DirectoryCleaner.getSuffixFileFilters(
|
||||||
listOfNotNull(
|
listOfNotNull(
|
||||||
@@ -153,9 +153,9 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
|
|||||||
configs.proversConfig.proverA.proofAggregation.inprogressRequestWritingSuffix,
|
configs.proversConfig.proverA.proofAggregation.inprogressRequestWritingSuffix,
|
||||||
configs.proversConfig.proverB?.execution?.inprogressRequestWritingSuffix,
|
configs.proversConfig.proverB?.execution?.inprogressRequestWritingSuffix,
|
||||||
configs.proversConfig.proverB?.blobCompression?.inprogressRequestWritingSuffix,
|
configs.proversConfig.proverB?.blobCompression?.inprogressRequestWritingSuffix,
|
||||||
configs.proversConfig.proverB?.proofAggregation?.inprogressRequestWritingSuffix
|
configs.proversConfig.proverB?.proofAggregation?.inprogressRequestWritingSuffix,
|
||||||
)
|
),
|
||||||
) + DirectoryCleaner.JSON_FILE_FILTER
|
) + DirectoryCleaner.JSON_FILE_FILTER,
|
||||||
)
|
)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -176,7 +176,7 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
|
|||||||
SafeFuture.allOf(
|
SafeFuture.allOf(
|
||||||
l1App.stop(),
|
l1App.stop(),
|
||||||
SafeFuture.fromRunnable { l2Web3jClient.shutdown() },
|
SafeFuture.fromRunnable { l2Web3jClient.shutdown() },
|
||||||
api.stop().toSafeFuture()
|
api.stop().toSafeFuture(),
|
||||||
).thenApply {
|
).thenApply {
|
||||||
LoadBalancingJsonRpcClient.stop()
|
LoadBalancingJsonRpcClient.stop()
|
||||||
}.thenCompose {
|
}.thenCompose {
|
||||||
@@ -201,7 +201,7 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
|
|||||||
database = dbConfig.schema,
|
database = dbConfig.schema,
|
||||||
target = dbVersion,
|
target = dbVersion,
|
||||||
username = dbConfig.username,
|
username = dbConfig.username,
|
||||||
password = dbConfig.password.value
|
password = dbConfig.password.value,
|
||||||
)
|
)
|
||||||
return Db.vertxSqlClient(
|
return Db.vertxSqlClient(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
@@ -211,7 +211,7 @@ class CoordinatorApp(private val configs: CoordinatorConfig) {
|
|||||||
username = dbConfig.username,
|
username = dbConfig.username,
|
||||||
password = dbConfig.password.value,
|
password = dbConfig.password.value,
|
||||||
maxPoolSize = dbConfig.transactionalPoolSize,
|
maxPoolSize = dbConfig.transactionalPoolSize,
|
||||||
pipeliningLimit = dbConfig.readPipeliningLimit
|
pipeliningLimit = dbConfig.readPipeliningLimit,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import java.util.concurrent.Callable
|
|||||||
synopsisHeading = "%n",
|
synopsisHeading = "%n",
|
||||||
descriptionHeading = "%nDescription:%n%n",
|
descriptionHeading = "%nDescription:%n%n",
|
||||||
optionListHeading = "%nOptions:%n",
|
optionListHeading = "%nOptions:%n",
|
||||||
footerHeading = "%n"
|
footerHeading = "%n",
|
||||||
)
|
)
|
||||||
class CoordinatorAppCli
|
class CoordinatorAppCli
|
||||||
internal constructor(private val errorWriter: PrintWriter, private val startAction: StartAction) :
|
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"],
|
names = ["--traces-limits-v2"],
|
||||||
paramLabel = "<FILE>",
|
paramLabel = "<FILE>",
|
||||||
description = ["Prover traces limits for linea besu"],
|
description = ["Prover traces limits for linea besu"],
|
||||||
arity = "1"
|
arity = "1",
|
||||||
)
|
)
|
||||||
private val tracesLimitsV2File: File? = null
|
private val tracesLimitsV2File: File? = null
|
||||||
|
|
||||||
@@ -40,27 +40,24 @@ internal constructor(private val errorWriter: PrintWriter, private val startActi
|
|||||||
names = ["--smart-contract-errors"],
|
names = ["--smart-contract-errors"],
|
||||||
paramLabel = "<FILE>",
|
paramLabel = "<FILE>",
|
||||||
description = ["Smart contract error codes"],
|
description = ["Smart contract error codes"],
|
||||||
arity = "1"
|
arity = "1",
|
||||||
)
|
)
|
||||||
|
|
||||||
private val smartContractErrorsFile: File? = null
|
private val smartContractErrorsFile: File? = null
|
||||||
|
|
||||||
@CommandLine.Option(
|
@CommandLine.Option(
|
||||||
names = ["--gas-price-cap-time-of-day-multipliers"],
|
names = ["--gas-price-cap-time-of-day-multipliers"],
|
||||||
paramLabel = "<FILE>",
|
paramLabel = "<FILE>",
|
||||||
description = ["Time-of-day multipliers for calculation of L1 dynamic gas price caps"],
|
description = ["Time-of-day multipliers for calculation of L1 dynamic gas price caps"],
|
||||||
arity = "1"
|
arity = "1",
|
||||||
)
|
)
|
||||||
|
|
||||||
private val gasPriceCapTimeOfDayMultipliersFile: File? = null
|
private val gasPriceCapTimeOfDayMultipliersFile: File? = null
|
||||||
|
|
||||||
@CommandLine.Option(
|
@CommandLine.Option(
|
||||||
names = ["--check-configs-only"],
|
names = ["--check-configs-only"],
|
||||||
paramLabel = "<BOOLEAN>",
|
paramLabel = "<BOOLEAN>",
|
||||||
description = ["Validates configuration files only, without starting the application."],
|
description = ["Validates configuration files only, without starting the application."],
|
||||||
arity = "0..1"
|
arity = "0..1",
|
||||||
)
|
)
|
||||||
|
|
||||||
private var checkConfigsOnly: Boolean = false
|
private var checkConfigsOnly: Boolean = false
|
||||||
|
|
||||||
override fun call(): Int {
|
override fun call(): Int {
|
||||||
@@ -97,7 +94,7 @@ internal constructor(private val errorWriter: PrintWriter, private val startActi
|
|||||||
tracesLimitsFileV2 = tracesLimitsV2File.toPath(),
|
tracesLimitsFileV2 = tracesLimitsV2File.toPath(),
|
||||||
smartContractErrorsFile = smartContractErrorsFile.toPath(),
|
smartContractErrorsFile = smartContractErrorsFile.toPath(),
|
||||||
gasPriceCapTimeOfDayMultipliersFile = gasPriceCapTimeOfDayMultipliersFile.toPath(),
|
gasPriceCapTimeOfDayMultipliersFile = gasPriceCapTimeOfDayMultipliersFile.toPath(),
|
||||||
logger = logger
|
logger = logger,
|
||||||
)
|
)
|
||||||
|
|
||||||
if (checkConfigsOnly) {
|
if (checkConfigsOnly) {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class CoordinatorAppMain {
|
|||||||
// Messages in App.stop won't appear in the logs
|
// Messages in App.stop won't appear in the logs
|
||||||
Configurator.shutdown(LogManager.getContext() as LoggerContext)
|
Configurator.shutdown(LogManager.getContext() as LoggerContext)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
app.start()
|
app.start()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ class L1DependentApp(
|
|||||||
private val aggregationsRepository: AggregationsRepository,
|
private val aggregationsRepository: AggregationsRepository,
|
||||||
l1FeeHistoriesRepository: FeeHistoriesRepositoryWithCache,
|
l1FeeHistoriesRepository: FeeHistoriesRepositoryWithCache,
|
||||||
private val smartContractErrors: SmartContractErrors,
|
private val smartContractErrors: SmartContractErrors,
|
||||||
private val metricsFacade: MetricsFacade
|
private val metricsFacade: MetricsFacade,
|
||||||
) : LongRunningService {
|
) : LongRunningService {
|
||||||
private val log = LogManager.getLogger(this::class.java)
|
private val log = LogManager.getLogger(this::class.java)
|
||||||
|
|
||||||
@@ -132,13 +132,13 @@ class L1DependentApp(
|
|||||||
private val l2TransactionManager = createTransactionManager(
|
private val l2TransactionManager = createTransactionManager(
|
||||||
vertx,
|
vertx,
|
||||||
configs.l2Signer,
|
configs.l2Signer,
|
||||||
l2Web3jClient
|
l2Web3jClient,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val l1Web3jClient = createWeb3jHttpClient(
|
private val l1Web3jClient = createWeb3jHttpClient(
|
||||||
rpcUrl = configs.l1.rpcEndpoint.toString(),
|
rpcUrl = configs.l1.rpcEndpoint.toString(),
|
||||||
log = LogManager.getLogger("clients.l1.eth-api"),
|
log = LogManager.getLogger("clients.l1.eth-api"),
|
||||||
pollingInterval = 1.seconds
|
pollingInterval = 1.seconds,
|
||||||
)
|
)
|
||||||
private val l1Web3jService = Web3jBlobExtended(HttpService(configs.l1.ethFeeHistoryEndpoint.toString()))
|
private val l1Web3jService = Web3jBlobExtended(HttpService(configs.l1.ethFeeHistoryEndpoint.toString()))
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ class L1DependentApp(
|
|||||||
private val proverClientFactory = ProverClientFactory(
|
private val proverClientFactory = ProverClientFactory(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
config = configs.proversConfig,
|
config = configs.proversConfig,
|
||||||
metricsFacade = metricsFacade
|
metricsFacade = metricsFacade,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val l2ExtendedWeb3j = ExtendedWeb3JImpl(l2Web3jClient)
|
private val l2ExtendedWeb3j = ExtendedWeb3JImpl(l2Web3jClient)
|
||||||
@@ -155,32 +155,32 @@ class L1DependentApp(
|
|||||||
private val finalizationTransactionManager = createTransactionManager(
|
private val finalizationTransactionManager = createTransactionManager(
|
||||||
vertx,
|
vertx,
|
||||||
configs.finalizationSigner,
|
configs.finalizationSigner,
|
||||||
l1Web3jClient
|
l1Web3jClient,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val l1MinPriorityFeeCalculator: FeesCalculator = WMAFeesCalculator(
|
private val l1MinPriorityFeeCalculator: FeesCalculator = WMAFeesCalculator(
|
||||||
WMAFeesCalculator.Config(
|
WMAFeesCalculator.Config(
|
||||||
baseFeeCoefficient = 0.0,
|
baseFeeCoefficient = 0.0,
|
||||||
priorityFeeWmaCoefficient = 1.0
|
priorityFeeWmaCoefficient = 1.0,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val l1DataSubmissionPriorityFeeCalculator: FeesCalculator = BoundableFeeCalculator(
|
private val l1DataSubmissionPriorityFeeCalculator: FeesCalculator = BoundableFeeCalculator(
|
||||||
BoundableFeeCalculator.Config(
|
BoundableFeeCalculator.Config(
|
||||||
feeUpperBound = configs.blobSubmission.priorityFeePerGasUpperBound.toDouble(),
|
feeUpperBound = configs.blobSubmission.priorityFeePerGasUpperBound.toDouble(),
|
||||||
feeLowerBound = configs.blobSubmission.priorityFeePerGasLowerBound.toDouble(),
|
feeLowerBound = configs.blobSubmission.priorityFeePerGasLowerBound.toDouble(),
|
||||||
feeMargin = 0.0
|
feeMargin = 0.0,
|
||||||
),
|
),
|
||||||
l1MinPriorityFeeCalculator
|
l1MinPriorityFeeCalculator,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val l1FinalizationPriorityFeeCalculator: FeesCalculator = BoundableFeeCalculator(
|
private val l1FinalizationPriorityFeeCalculator: FeesCalculator = BoundableFeeCalculator(
|
||||||
BoundableFeeCalculator.Config(
|
BoundableFeeCalculator.Config(
|
||||||
feeUpperBound = configs.l1.maxPriorityFeePerGasCap.toDouble() * configs.l1.gasPriceCapMultiplierForFinalization,
|
feeUpperBound = configs.l1.maxPriorityFeePerGasCap.toDouble() * configs.l1.gasPriceCapMultiplierForFinalization,
|
||||||
feeLowerBound = 0.0,
|
feeLowerBound = 0.0,
|
||||||
feeMargin = 0.0
|
feeMargin = 0.0,
|
||||||
),
|
),
|
||||||
l1MinPriorityFeeCalculator
|
l1MinPriorityFeeCalculator,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val feesFetcher: FeesFetcher = FeeHistoryFetcherImpl(
|
private val feesFetcher: FeesFetcher = FeeHistoryFetcherImpl(
|
||||||
@@ -188,13 +188,13 @@ class L1DependentApp(
|
|||||||
l1Web3jService,
|
l1Web3jService,
|
||||||
FeeHistoryFetcherImpl.Config(
|
FeeHistoryFetcherImpl.Config(
|
||||||
configs.l1.feeHistoryBlockCount.toUInt(),
|
configs.l1.feeHistoryBlockCount.toUInt(),
|
||||||
configs.l1.feeHistoryRewardPercentile
|
configs.l1.feeHistoryRewardPercentile,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val lineaRollupClient: LineaRollupSmartContractClientReadOnly = Web3JLineaRollupSmartContractClientReadOnly(
|
private val lineaRollupClient: LineaRollupSmartContractClientReadOnly = Web3JLineaRollupSmartContractClientReadOnly(
|
||||||
contractAddress = configs.l1.zkEvmContractAddress,
|
contractAddress = configs.l1.zkEvmContractAddress,
|
||||||
web3j = l1Web3jClient
|
web3j = l1Web3jClient,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val l1FinalizationMonitor = run {
|
private val l1FinalizationMonitor = run {
|
||||||
@@ -202,11 +202,11 @@ class L1DependentApp(
|
|||||||
config =
|
config =
|
||||||
FinalizationMonitorImpl.Config(
|
FinalizationMonitorImpl.Config(
|
||||||
pollingInterval = configs.l1.finalizationPollingInterval.toKotlinDuration(),
|
pollingInterval = configs.l1.finalizationPollingInterval.toKotlinDuration(),
|
||||||
l1QueryBlockTag = configs.l1.l1QueryBlockTag
|
l1QueryBlockTag = configs.l1.l1QueryBlockTag,
|
||||||
),
|
),
|
||||||
contract = lineaRollupClient,
|
contract = lineaRollupClient,
|
||||||
l2Client = l2Web3jClient,
|
l2Client = l2Web3jClient,
|
||||||
vertx = vertx
|
vertx = vertx,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,7 +215,7 @@ class L1DependentApp(
|
|||||||
httpJsonRpcClientFactory = httpJsonRpcClientFactory,
|
httpJsonRpcClientFactory = httpJsonRpcClientFactory,
|
||||||
lineaRollupClient = lineaRollupClient,
|
lineaRollupClient = lineaRollupClient,
|
||||||
l2Web3jClient = l2Web3jClient,
|
l2Web3jClient = l2Web3jClient,
|
||||||
vertx = vertx
|
vertx = vertx,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val gasPriceCapProvider =
|
private val gasPriceCapProvider =
|
||||||
@@ -246,11 +246,11 @@ class L1DependentApp(
|
|||||||
finalizationTargetMaxDelay =
|
finalizationTargetMaxDelay =
|
||||||
configs.l1DynamicGasPriceCapService.gasPriceCapCalculation.finalizationTargetMaxDelay.toKotlinDuration(),
|
configs.l1DynamicGasPriceCapService.gasPriceCapCalculation.finalizationTargetMaxDelay.toKotlinDuration(),
|
||||||
gasPriceCapsCoefficient =
|
gasPriceCapsCoefficient =
|
||||||
configs.l1DynamicGasPriceCapService.gasPriceCapCalculation.gasPriceCapsCheckCoefficient
|
configs.l1DynamicGasPriceCapService.gasPriceCapCalculation.gasPriceCapsCheckCoefficient,
|
||||||
),
|
),
|
||||||
l2ExtendedWeb3JClient = l2ExtendedWeb3j,
|
l2ExtendedWeb3JClient = l2ExtendedWeb3j,
|
||||||
feeHistoriesRepository = l1FeeHistoriesRepository,
|
feeHistoriesRepository = l1FeeHistoriesRepository,
|
||||||
gasPriceCapCalculator = l1GasPriceCapCalculator
|
gasPriceCapCalculator = l1GasPriceCapCalculator,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
@@ -261,10 +261,10 @@ class L1DependentApp(
|
|||||||
config = GasPriceCapProviderForDataSubmission.Config(
|
config = GasPriceCapProviderForDataSubmission.Config(
|
||||||
maxPriorityFeePerGasCap = configs.l1.maxPriorityFeePerGasCap,
|
maxPriorityFeePerGasCap = configs.l1.maxPriorityFeePerGasCap,
|
||||||
maxFeePerGasCap = configs.l1.maxFeePerGasCap,
|
maxFeePerGasCap = configs.l1.maxFeePerGasCap,
|
||||||
maxFeePerBlobGasCap = configs.l1.maxFeePerBlobGasCap
|
maxFeePerBlobGasCap = configs.l1.maxFeePerBlobGasCap,
|
||||||
),
|
),
|
||||||
gasPriceCapProvider = gasPriceCapProvider!!,
|
gasPriceCapProvider = gasPriceCapProvider!!,
|
||||||
metricsFacade = metricsFacade
|
metricsFacade = metricsFacade,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
@@ -275,10 +275,10 @@ class L1DependentApp(
|
|||||||
config = GasPriceCapProviderForFinalization.Config(
|
config = GasPriceCapProviderForFinalization.Config(
|
||||||
maxPriorityFeePerGasCap = configs.l1.maxPriorityFeePerGasCap,
|
maxPriorityFeePerGasCap = configs.l1.maxPriorityFeePerGasCap,
|
||||||
maxFeePerGasCap = configs.l1.maxFeePerGasCap,
|
maxFeePerGasCap = configs.l1.maxFeePerGasCap,
|
||||||
gasPriceCapMultiplier = configs.l1.gasPriceCapMultiplierForFinalization
|
gasPriceCapMultiplier = configs.l1.gasPriceCapMultiplierForFinalization,
|
||||||
),
|
),
|
||||||
gasPriceCapProvider = gasPriceCapProvider!!,
|
gasPriceCapProvider = gasPriceCapProvider!!,
|
||||||
metricsFacade = metricsFacade
|
metricsFacade = metricsFacade,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
@@ -287,11 +287,11 @@ class L1DependentApp(
|
|||||||
private val lastFinalizedBlock = lastFinalizedBlock().get()
|
private val lastFinalizedBlock = lastFinalizedBlock().get()
|
||||||
private val lastProcessedBlockNumber = resumeConflationFrom(
|
private val lastProcessedBlockNumber = resumeConflationFrom(
|
||||||
aggregationsRepository,
|
aggregationsRepository,
|
||||||
lastFinalizedBlock
|
lastFinalizedBlock,
|
||||||
).get()
|
).get()
|
||||||
private val lastConsecutiveAggregatedBlockNumber = resumeAggregationFrom(
|
private val lastConsecutiveAggregatedBlockNumber = resumeAggregationFrom(
|
||||||
aggregationsRepository,
|
aggregationsRepository,
|
||||||
lastFinalizedBlock
|
lastFinalizedBlock,
|
||||||
).get()
|
).get()
|
||||||
|
|
||||||
private fun createDeadlineConflationCalculatorRunner(): DeadlineConflationCalculatorRunner {
|
private fun createDeadlineConflationCalculatorRunner(): DeadlineConflationCalculatorRunner {
|
||||||
@@ -301,15 +301,15 @@ class L1DependentApp(
|
|||||||
config = ConflationCalculatorByTimeDeadline.Config(
|
config = ConflationCalculatorByTimeDeadline.Config(
|
||||||
conflationDeadline = configs.conflation.conflationDeadline.toKotlinDuration(),
|
conflationDeadline = configs.conflation.conflationDeadline.toKotlinDuration(),
|
||||||
conflationDeadlineLastBlockConfirmationDelay =
|
conflationDeadlineLastBlockConfirmationDelay =
|
||||||
configs.conflation.conflationDeadlineLastBlockConfirmationDelay.toKotlinDuration()
|
configs.conflation.conflationDeadlineLastBlockConfirmationDelay.toKotlinDuration(),
|
||||||
),
|
),
|
||||||
lastBlockNumber = lastProcessedBlockNumber,
|
lastBlockNumber = lastProcessedBlockNumber,
|
||||||
clock = Clock.System,
|
clock = Clock.System,
|
||||||
latestBlockProvider = GethCliqueSafeBlockProvider(
|
latestBlockProvider = GethCliqueSafeBlockProvider(
|
||||||
l2ExtendedWeb3j.web3jClient,
|
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) {
|
if (configs.conflation.blocksLimit != null) {
|
||||||
calculators.add(
|
calculators.add(
|
||||||
ConflationCalculatorByBlockLimit(
|
ConflationCalculatorByBlockLimit(
|
||||||
blockLimit = configs.conflation.blocksLimit.toUInt()
|
blockLimit = configs.conflation.blocksLimit.toUInt(),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -330,15 +330,15 @@ class L1DependentApp(
|
|||||||
if (configs.conflation.conflationTargetEndBlockNumbers.isNotEmpty()) {
|
if (configs.conflation.conflationTargetEndBlockNumbers.isNotEmpty()) {
|
||||||
calculators.add(
|
calculators.add(
|
||||||
ConflationCalculatorByTargetBlockNumbers(
|
ConflationCalculatorByTargetBlockNumbers(
|
||||||
targetEndBlockNumbers = configs.conflation.conflationTargetEndBlockNumbers
|
targetEndBlockNumbers = configs.conflation.conflationTargetEndBlockNumbers,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createCalculatorsForBlobsAndConflation(
|
private fun createCalculatorsForBlobsAndConflation(
|
||||||
logger: Logger,
|
logger: Logger,
|
||||||
compressedBlobCalculator: ConflationCalculatorByDataCompressed
|
compressedBlobCalculator: ConflationCalculatorByDataCompressed,
|
||||||
): List<ConflationCalculator> {
|
): List<ConflationCalculator> {
|
||||||
val calculators: MutableList<ConflationCalculator> =
|
val calculators: MutableList<ConflationCalculator> =
|
||||||
mutableListOf(
|
mutableListOf(
|
||||||
@@ -346,9 +346,9 @@ class L1DependentApp(
|
|||||||
tracesCountersLimit = configs.conflation.tracesLimitsV2,
|
tracesCountersLimit = configs.conflation.tracesLimitsV2,
|
||||||
emptyTracesCounters = TracesCountersV2.EMPTY_TRACES_COUNT,
|
emptyTracesCounters = TracesCountersV2.EMPTY_TRACES_COUNT,
|
||||||
metricsFacade = metricsFacade,
|
metricsFacade = metricsFacade,
|
||||||
log = logger
|
log = logger,
|
||||||
),
|
),
|
||||||
compressedBlobCalculator
|
compressedBlobCalculator,
|
||||||
)
|
)
|
||||||
addBlocksLimitCalculatorIfDefined(calculators)
|
addBlocksLimitCalculatorIfDefined(calculators)
|
||||||
addTargetEndBlockConflationCalculatorIfDefined(calculators)
|
addTargetEndBlockConflationCalculatorIfDefined(calculators)
|
||||||
@@ -363,18 +363,18 @@ class L1DependentApp(
|
|||||||
val blobCompressor = GoBackedBlobCompressor.getInstance(
|
val blobCompressor = GoBackedBlobCompressor.getInstance(
|
||||||
compressorVersion = compressorVersion,
|
compressorVersion = compressorVersion,
|
||||||
dataLimit = configs.blobCompression.blobSizeLimit.toUInt(),
|
dataLimit = configs.blobCompression.blobSizeLimit.toUInt(),
|
||||||
metricsFacade = metricsFacade
|
metricsFacade = metricsFacade,
|
||||||
)
|
)
|
||||||
|
|
||||||
val compressedBlobCalculator = ConflationCalculatorByDataCompressed(
|
val compressedBlobCalculator = ConflationCalculatorByDataCompressed(
|
||||||
blobCompressor = blobCompressor
|
blobCompressor = blobCompressor,
|
||||||
)
|
)
|
||||||
val globalCalculator = GlobalBlockConflationCalculator(
|
val globalCalculator = GlobalBlockConflationCalculator(
|
||||||
lastBlockNumber = lastProcessedBlockNumber,
|
lastBlockNumber = lastProcessedBlockNumber,
|
||||||
syncCalculators = createCalculatorsForBlobsAndConflation(logger, compressedBlobCalculator),
|
syncCalculators = createCalculatorsForBlobsAndConflation(logger, compressedBlobCalculator),
|
||||||
deferredTriggerConflationCalculators = listOf(deadlineConflationCalculatorRunnerNew),
|
deferredTriggerConflationCalculators = listOf(deadlineConflationCalculatorRunnerNew),
|
||||||
emptyTracesCounters = TracesCountersV2.EMPTY_TRACES_COUNT,
|
emptyTracesCounters = TracesCountersV2.EMPTY_TRACES_COUNT,
|
||||||
log = logger
|
log = logger,
|
||||||
)
|
)
|
||||||
|
|
||||||
val batchesLimit =
|
val batchesLimit =
|
||||||
@@ -384,7 +384,7 @@ class L1DependentApp(
|
|||||||
conflationCalculator = globalCalculator,
|
conflationCalculator = globalCalculator,
|
||||||
blobCalculator = compressedBlobCalculator,
|
blobCalculator = compressedBlobCalculator,
|
||||||
metricsFacade = metricsFacade,
|
metricsFacade = metricsFacade,
|
||||||
batchesLimit = batchesLimit
|
batchesLimit = batchesLimit,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
private val conflationService: ConflationService =
|
private val conflationService: ConflationService =
|
||||||
@@ -396,7 +396,7 @@ class L1DependentApp(
|
|||||||
maxInflightRequestsPerClient = configs.stateManager.requestLimitPerEndpoint,
|
maxInflightRequestsPerClient = configs.stateManager.requestLimitPerEndpoint,
|
||||||
requestRetry = configs.stateManager.requestRetryConfig,
|
requestRetry = configs.stateManager.requestRetryConfig,
|
||||||
zkStateManagerVersion = configs.stateManager.version,
|
zkStateManagerVersion = configs.stateManager.version,
|
||||||
logger = LogManager.getLogger("clients.StateManagerShomeiClient")
|
logger = LogManager.getLogger("clients.StateManagerShomeiClient"),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val lineaSmartContractClientForDataSubmission: LineaRollupSmartContractClient = run {
|
private val lineaSmartContractClientForDataSubmission: LineaRollupSmartContractClient = run {
|
||||||
@@ -411,26 +411,26 @@ class L1DependentApp(
|
|||||||
gasLimit = configs.l1.gasLimit,
|
gasLimit = configs.l1.gasLimit,
|
||||||
maxFeePerGasCap = configs.l1.maxFeePerGasCap,
|
maxFeePerGasCap = configs.l1.maxFeePerGasCap,
|
||||||
maxPriorityFeePerGasCap = configs.l1.maxPriorityFeePerGasCap,
|
maxPriorityFeePerGasCap = configs.l1.maxPriorityFeePerGasCap,
|
||||||
maxFeePerBlobGasCap = configs.l1.maxFeePerBlobGasCap
|
maxFeePerBlobGasCap = configs.l1.maxFeePerBlobGasCap,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
createLineaRollupContractClient(
|
createLineaRollupContractClient(
|
||||||
l1Config = configs.l1,
|
l1Config = configs.l1,
|
||||||
transactionManager = createTransactionManager(
|
transactionManager = createTransactionManager(
|
||||||
vertx,
|
vertx,
|
||||||
configs.dataSubmissionSigner,
|
configs.dataSubmissionSigner,
|
||||||
l1Web3jClient
|
l1Web3jClient,
|
||||||
),
|
),
|
||||||
contractGasProvider = primaryOrFallbackGasProvider,
|
contractGasProvider = primaryOrFallbackGasProvider,
|
||||||
web3jClient = l1Web3jClient,
|
web3jClient = l1Web3jClient,
|
||||||
smartContractErrors = smartContractErrors,
|
smartContractErrors = smartContractErrors,
|
||||||
useEthEstimateGas = configs.blobSubmission.useEthEstimateGas
|
useEthEstimateGas = configs.blobSubmission.useEthEstimateGas,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val genesisStateProvider = GenesisStateProvider(
|
private val genesisStateProvider = GenesisStateProvider(
|
||||||
configs.l1.genesisStateRootHash,
|
configs.l1.genesisStateRootHash,
|
||||||
configs.l1.genesisShnarfV6
|
configs.l1.genesisShnarfV6,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val blobCompressionProofCoordinator = run {
|
private val blobCompressionProofCoordinator = run {
|
||||||
@@ -440,14 +440,14 @@ class L1DependentApp(
|
|||||||
category = LineaMetricsCategory.BLOB,
|
category = LineaMetricsCategory.BLOB,
|
||||||
name = "proven.highest.block.number",
|
name = "proven.highest.block.number",
|
||||||
description = "Highest proven blob compression block number",
|
description = "Highest proven blob compression block number",
|
||||||
measurementSupplier = highestProvenBlobTracker
|
measurementSupplier = highestProvenBlobTracker,
|
||||||
)
|
)
|
||||||
highestProvenBlobTracker
|
highestProvenBlobTracker
|
||||||
}
|
}
|
||||||
val blobCompressionProofHandler: (BlobCompressionProofUpdate) -> SafeFuture<*> = SimpleCompositeSafeFutureHandler(
|
val blobCompressionProofHandler: (BlobCompressionProofUpdate) -> SafeFuture<*> = SimpleCompositeSafeFutureHandler(
|
||||||
listOf(
|
listOf(
|
||||||
maxProvenBlobCache
|
maxProvenBlobCache,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
val blobCompressionProofCoordinator = BlobCompressionProofCoordinator(
|
val blobCompressionProofCoordinator = BlobCompressionProofCoordinator(
|
||||||
@@ -457,33 +457,33 @@ class L1DependentApp(
|
|||||||
rollingBlobShnarfCalculator = RollingBlobShnarfCalculator(
|
rollingBlobShnarfCalculator = RollingBlobShnarfCalculator(
|
||||||
blobShnarfCalculator = GoBackedBlobShnarfCalculator(
|
blobShnarfCalculator = GoBackedBlobShnarfCalculator(
|
||||||
version = ShnarfCalculatorVersion.V1_2,
|
version = ShnarfCalculatorVersion.V1_2,
|
||||||
metricsFacade = metricsFacade
|
metricsFacade = metricsFacade,
|
||||||
),
|
),
|
||||||
blobsRepository = blobsRepository,
|
blobsRepository = blobsRepository,
|
||||||
genesisShnarf = genesisStateProvider.shnarf
|
genesisShnarf = genesisStateProvider.shnarf,
|
||||||
),
|
),
|
||||||
blobZkStateProvider = BlobZkStateProviderImpl(
|
blobZkStateProvider = BlobZkStateProviderImpl(
|
||||||
zkStateClient = zkStateClient
|
zkStateClient = zkStateClient,
|
||||||
),
|
),
|
||||||
config = BlobCompressionProofCoordinator.Config(
|
config = BlobCompressionProofCoordinator.Config(
|
||||||
pollingInterval = configs.blobCompression.handlerPollingInterval.toKotlinDuration()
|
pollingInterval = configs.blobCompression.handlerPollingInterval.toKotlinDuration(),
|
||||||
),
|
),
|
||||||
blobCompressionProofHandler = blobCompressionProofHandler,
|
blobCompressionProofHandler = blobCompressionProofHandler,
|
||||||
metricsFacade = metricsFacade
|
metricsFacade = metricsFacade,
|
||||||
)
|
)
|
||||||
val highestUnprovenBlobTracker = HighestUnprovenBlobTracker(lastProcessedBlockNumber)
|
val highestUnprovenBlobTracker = HighestUnprovenBlobTracker(lastProcessedBlockNumber)
|
||||||
metricsFacade.createGauge(
|
metricsFacade.createGauge(
|
||||||
category = LineaMetricsCategory.BLOB,
|
category = LineaMetricsCategory.BLOB,
|
||||||
name = "unproven.highest.block.number",
|
name = "unproven.highest.block.number",
|
||||||
description = "Block number of highest unproven blob produced",
|
description = "Block number of highest unproven blob produced",
|
||||||
measurementSupplier = highestUnprovenBlobTracker
|
measurementSupplier = highestUnprovenBlobTracker,
|
||||||
)
|
)
|
||||||
|
|
||||||
val compositeSafeFutureHandler = SimpleCompositeSafeFutureHandler(
|
val compositeSafeFutureHandler = SimpleCompositeSafeFutureHandler(
|
||||||
listOf(
|
listOf(
|
||||||
blobCompressionProofCoordinator::handleBlob,
|
blobCompressionProofCoordinator::handleBlob,
|
||||||
highestUnprovenBlobTracker
|
highestUnprovenBlobTracker,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
conflationCalculator.onBlobCreation(compositeSafeFutureHandler)
|
conflationCalculator.onBlobCreation(compositeSafeFutureHandler)
|
||||||
blobCompressionProofCoordinator
|
blobCompressionProofCoordinator
|
||||||
@@ -494,14 +494,14 @@ class L1DependentApp(
|
|||||||
category = LineaMetricsCategory.BLOB,
|
category = LineaMetricsCategory.BLOB,
|
||||||
name = "highest.accepted.block.number",
|
name = "highest.accepted.block.number",
|
||||||
description = "Highest accepted blob end block number",
|
description = "Highest accepted blob end block number",
|
||||||
measurementSupplier = it
|
measurementSupplier = it,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val alreadySubmittedBlobsFilter =
|
private val alreadySubmittedBlobsFilter =
|
||||||
L1ShnarfBasedAlreadySubmittedBlobsFilter(
|
L1ShnarfBasedAlreadySubmittedBlobsFilter(
|
||||||
lineaRollup = lineaSmartContractClientForDataSubmission,
|
lineaRollup = lineaSmartContractClientForDataSubmission,
|
||||||
acceptedBlobEndBlockNumberConsumer = { highestAcceptedBlobTracker(it) }
|
acceptedBlobEndBlockNumberConsumer = { highestAcceptedBlobTracker(it) },
|
||||||
)
|
)
|
||||||
|
|
||||||
private val latestBlobSubmittedBlockNumberTracker = LatestBlobSubmittedBlockNumberTracker(0UL)
|
private val latestBlobSubmittedBlockNumberTracker = LatestBlobSubmittedBlockNumberTracker(0UL)
|
||||||
@@ -513,14 +513,14 @@ class L1DependentApp(
|
|||||||
category = LineaMetricsCategory.BLOB,
|
category = LineaMetricsCategory.BLOB,
|
||||||
name = "highest.submitted.on.l1",
|
name = "highest.submitted.on.l1",
|
||||||
description = "Highest submitted blob end block number on l1",
|
description = "Highest submitted blob end block number on l1",
|
||||||
measurementSupplier = { latestBlobSubmittedBlockNumberTracker.get() }
|
measurementSupplier = { latestBlobSubmittedBlockNumberTracker.get() },
|
||||||
)
|
)
|
||||||
|
|
||||||
val blobSubmissionDelayHistogram = metricsFacade.createHistogram(
|
val blobSubmissionDelayHistogram = metricsFacade.createHistogram(
|
||||||
category = LineaMetricsCategory.BLOB,
|
category = LineaMetricsCategory.BLOB,
|
||||||
name = "submission.delay",
|
name = "submission.delay",
|
||||||
description = "Delay between blob submission and end block timestamps",
|
description = "Delay between blob submission and end block timestamps",
|
||||||
baseUnit = "seconds"
|
baseUnit = "seconds",
|
||||||
)
|
)
|
||||||
|
|
||||||
val blobSubmittedEventConsumers: Map<Consumer<BlobSubmittedEvent>, String> = mapOf(
|
val blobSubmittedEventConsumers: Map<Consumer<BlobSubmittedEvent>, String> = mapOf(
|
||||||
@@ -529,7 +529,7 @@ class L1DependentApp(
|
|||||||
} to "Submitted Blob Tracker Consumer",
|
} to "Submitted Blob Tracker Consumer",
|
||||||
Consumer<BlobSubmittedEvent> { blobSubmission ->
|
Consumer<BlobSubmittedEvent> { blobSubmission ->
|
||||||
blobSubmissionDelayHistogram.record(blobSubmission.getSubmissionDelay().toDouble())
|
blobSubmissionDelayHistogram.record(blobSubmission.getSubmissionDelay().toDouble())
|
||||||
} to "Blob Submission Delay Consumer"
|
} to "Blob Submission Delay Consumer",
|
||||||
)
|
)
|
||||||
|
|
||||||
BlobSubmissionCoordinator.create(
|
BlobSubmissionCoordinator.create(
|
||||||
@@ -537,7 +537,7 @@ class L1DependentApp(
|
|||||||
configs.blobSubmission.dbPollingInterval.toKotlinDuration(),
|
configs.blobSubmission.dbPollingInterval.toKotlinDuration(),
|
||||||
configs.blobSubmission.proofSubmissionDelay.toKotlinDuration(),
|
configs.blobSubmission.proofSubmissionDelay.toKotlinDuration(),
|
||||||
configs.blobSubmission.maxBlobsToSubmitPerTick.toUInt(),
|
configs.blobSubmission.maxBlobsToSubmitPerTick.toUInt(),
|
||||||
configs.blobSubmission.targetBlobsToSendPerTransaction.toUInt()
|
configs.blobSubmission.targetBlobsToSendPerTransaction.toUInt(),
|
||||||
),
|
),
|
||||||
blobsRepository = blobsRepository,
|
blobsRepository = blobsRepository,
|
||||||
aggregationsRepository = aggregationsRepository,
|
aggregationsRepository = aggregationsRepository,
|
||||||
@@ -546,7 +546,7 @@ class L1DependentApp(
|
|||||||
alreadySubmittedBlobsFilter = alreadySubmittedBlobsFilter,
|
alreadySubmittedBlobsFilter = alreadySubmittedBlobsFilter,
|
||||||
blobSubmittedEventDispatcher = EventDispatcher(blobSubmittedEventConsumers),
|
blobSubmittedEventDispatcher = EventDispatcher(blobSubmittedEventConsumers),
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
clock = Clock.System
|
clock = Clock.System,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -554,14 +554,14 @@ class L1DependentApp(
|
|||||||
private val proofAggregationCoordinatorService: LongRunningService = run {
|
private val proofAggregationCoordinatorService: LongRunningService = run {
|
||||||
val maxBlobEndBlockNumberTracker = ConsecutiveProvenBlobsProviderWithLastEndBlockNumberTracker(
|
val maxBlobEndBlockNumberTracker = ConsecutiveProvenBlobsProviderWithLastEndBlockNumberTracker(
|
||||||
aggregationsRepository,
|
aggregationsRepository,
|
||||||
lastProcessedBlockNumber
|
lastProcessedBlockNumber,
|
||||||
)
|
)
|
||||||
|
|
||||||
metricsFacade.createGauge(
|
metricsFacade.createGauge(
|
||||||
category = LineaMetricsCategory.BLOB,
|
category = LineaMetricsCategory.BLOB,
|
||||||
name = "proven.highest.consecutive.block.number",
|
name = "proven.highest.consecutive.block.number",
|
||||||
description = "Highest consecutive proven blob compression block number",
|
description = "Highest consecutive proven blob compression block number",
|
||||||
measurementSupplier = maxBlobEndBlockNumberTracker
|
measurementSupplier = maxBlobEndBlockNumberTracker,
|
||||||
)
|
)
|
||||||
|
|
||||||
val highestAggregationTracker = HighestULongTracker(lastProcessedBlockNumber)
|
val highestAggregationTracker = HighestULongTracker(lastProcessedBlockNumber)
|
||||||
@@ -569,7 +569,7 @@ class L1DependentApp(
|
|||||||
category = LineaMetricsCategory.AGGREGATION,
|
category = LineaMetricsCategory.AGGREGATION,
|
||||||
name = "proven.highest.block.number",
|
name = "proven.highest.block.number",
|
||||||
description = "Highest proven aggregation block number",
|
description = "Highest proven aggregation block number",
|
||||||
measurementSupplier = highestAggregationTracker
|
measurementSupplier = highestAggregationTracker,
|
||||||
)
|
)
|
||||||
|
|
||||||
ProofAggregationCoordinatorService
|
ProofAggregationCoordinatorService
|
||||||
@@ -581,7 +581,7 @@ class L1DependentApp(
|
|||||||
aggregationDeadline = configs.proofAggregation.aggregationDeadline.toKotlinDuration(),
|
aggregationDeadline = configs.proofAggregation.aggregationDeadline.toKotlinDuration(),
|
||||||
latestBlockProvider = GethCliqueSafeBlockProvider(
|
latestBlockProvider = GethCliqueSafeBlockProvider(
|
||||||
l2ExtendedWeb3j.web3jClient,
|
l2ExtendedWeb3j.web3jClient,
|
||||||
GethCliqueSafeBlockProvider.Config(configs.l2.blocksToFinalization.toLong())
|
GethCliqueSafeBlockProvider.Config(configs.l2.blocksToFinalization.toLong()),
|
||||||
),
|
),
|
||||||
maxProofsPerAggregation = configs.proofAggregation.aggregationProofsLimit.toUInt(),
|
maxProofsPerAggregation = configs.proofAggregation.aggregationProofsLimit.toUInt(),
|
||||||
startBlockNumberInclusive = lastConsecutiveAggregatedBlockNumber + 1u,
|
startBlockNumberInclusive = lastConsecutiveAggregatedBlockNumber + 1u,
|
||||||
@@ -592,9 +592,9 @@ class L1DependentApp(
|
|||||||
l2Web3jClient,
|
l2Web3jClient,
|
||||||
requestRetryConfig = linea.domain.RetryConfig(
|
requestRetryConfig = linea.domain.RetryConfig(
|
||||||
backoffDelay = 1.seconds,
|
backoffDelay = 1.seconds,
|
||||||
failuresWarningThreshold = 3u
|
failuresWarningThreshold = 3u,
|
||||||
),
|
),
|
||||||
vertx = vertx
|
vertx = vertx,
|
||||||
),
|
),
|
||||||
l2MessageService = Web3JL2MessageServiceSmartContractClient.create(
|
l2MessageService = Web3JL2MessageServiceSmartContractClient.create(
|
||||||
web3jClient = l2Web3jClient,
|
web3jClient = l2Web3jClient,
|
||||||
@@ -605,13 +605,13 @@ class L1DependentApp(
|
|||||||
feeHistoryRewardPercentile = configs.l2.feeHistoryRewardPercentile,
|
feeHistoryRewardPercentile = configs.l2.feeHistoryRewardPercentile,
|
||||||
transactionManager = l2TransactionManager,
|
transactionManager = l2TransactionManager,
|
||||||
smartContractErrors = smartContractErrors,
|
smartContractErrors = smartContractErrors,
|
||||||
smartContractDeploymentBlockNumber = configs.l2.messageServiceDeploymentBlockNumber
|
smartContractDeploymentBlockNumber = configs.l2.messageServiceDeploymentBlockNumber,
|
||||||
),
|
),
|
||||||
aggregationDeadlineDelay = configs.conflation.conflationDeadlineLastBlockConfirmationDelay.toKotlinDuration(),
|
aggregationDeadlineDelay = configs.conflation.conflationDeadlineLastBlockConfirmationDelay.toKotlinDuration(),
|
||||||
targetEndBlockNumbers = configs.proofAggregation.targetEndBlocks,
|
targetEndBlockNumbers = configs.proofAggregation.targetEndBlocks,
|
||||||
metricsFacade = metricsFacade,
|
metricsFacade = metricsFacade,
|
||||||
provenAggregationEndBlockNumberConsumer = { highestAggregationTracker(it) },
|
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.maxPriorityFeePerGasCap.toDouble() *
|
||||||
configs.l1.gasPriceCapMultiplierForFinalization
|
configs.l1.gasPriceCapMultiplierForFinalization
|
||||||
).toULong(),
|
).toULong(),
|
||||||
maxFeePerBlobGasCap = configs.l1.maxFeePerBlobGasCap
|
maxFeePerBlobGasCap = configs.l1.maxFeePerBlobGasCap,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
val lineaSmartContractClientForFinalization: LineaRollupSmartContractClient = createLineaRollupContractClient(
|
val lineaSmartContractClientForFinalization: LineaRollupSmartContractClient = createLineaRollupContractClient(
|
||||||
l1Config = configs.l1,
|
l1Config = configs.l1,
|
||||||
@@ -645,7 +645,7 @@ class L1DependentApp(
|
|||||||
contractGasProvider = primaryOrFallbackGasProvider,
|
contractGasProvider = primaryOrFallbackGasProvider,
|
||||||
web3jClient = l1Web3jClient,
|
web3jClient = l1Web3jClient,
|
||||||
smartContractErrors = smartContractErrors,
|
smartContractErrors = smartContractErrors,
|
||||||
useEthEstimateGas = configs.aggregationFinalization.useEthEstimateGas
|
useEthEstimateGas = configs.aggregationFinalization.useEthEstimateGas,
|
||||||
)
|
)
|
||||||
|
|
||||||
val latestFinalizationSubmittedBlockNumberTracker = LatestFinalizationSubmittedBlockNumberTracker(0UL)
|
val latestFinalizationSubmittedBlockNumberTracker = LatestFinalizationSubmittedBlockNumberTracker(0UL)
|
||||||
@@ -653,14 +653,14 @@ class L1DependentApp(
|
|||||||
category = LineaMetricsCategory.AGGREGATION,
|
category = LineaMetricsCategory.AGGREGATION,
|
||||||
name = "highest.submitted.on.l1",
|
name = "highest.submitted.on.l1",
|
||||||
description = "Highest submitted finalization end block number on l1",
|
description = "Highest submitted finalization end block number on l1",
|
||||||
measurementSupplier = { latestFinalizationSubmittedBlockNumberTracker.get() }
|
measurementSupplier = { latestFinalizationSubmittedBlockNumberTracker.get() },
|
||||||
)
|
)
|
||||||
|
|
||||||
val finalizationSubmissionDelayHistogram = metricsFacade.createHistogram(
|
val finalizationSubmissionDelayHistogram = metricsFacade.createHistogram(
|
||||||
category = LineaMetricsCategory.AGGREGATION,
|
category = LineaMetricsCategory.AGGREGATION,
|
||||||
name = "submission.delay",
|
name = "submission.delay",
|
||||||
description = "Delay between finalization submission and end block timestamps",
|
description = "Delay between finalization submission and end block timestamps",
|
||||||
baseUnit = "seconds"
|
baseUnit = "seconds",
|
||||||
)
|
)
|
||||||
|
|
||||||
val submittedFinalizationConsumers: Map<Consumer<FinalizationSubmittedEvent>, String> = mapOf(
|
val submittedFinalizationConsumers: Map<Consumer<FinalizationSubmittedEvent>, String> = mapOf(
|
||||||
@@ -669,13 +669,13 @@ class L1DependentApp(
|
|||||||
} to "Finalization Submission Consumer",
|
} to "Finalization Submission Consumer",
|
||||||
Consumer<FinalizationSubmittedEvent> { finalizationSubmission ->
|
Consumer<FinalizationSubmittedEvent> { finalizationSubmission ->
|
||||||
finalizationSubmissionDelayHistogram.record(finalizationSubmission.getSubmissionDelay().toDouble())
|
finalizationSubmissionDelayHistogram.record(finalizationSubmission.getSubmissionDelay().toDouble())
|
||||||
} to "Finalization Submission Delay Consumer"
|
} to "Finalization Submission Delay Consumer",
|
||||||
)
|
)
|
||||||
|
|
||||||
AggregationFinalizationCoordinator.create(
|
AggregationFinalizationCoordinator.create(
|
||||||
config = AggregationFinalizationCoordinator.Config(
|
config = AggregationFinalizationCoordinator.Config(
|
||||||
configs.aggregationFinalization.dbPollingInterval.toKotlinDuration(),
|
configs.aggregationFinalization.dbPollingInterval.toKotlinDuration(),
|
||||||
configs.aggregationFinalization.proofSubmissionDelay.toKotlinDuration()
|
configs.aggregationFinalization.proofSubmissionDelay.toKotlinDuration(),
|
||||||
),
|
),
|
||||||
aggregationsRepository = aggregationsRepository,
|
aggregationsRepository = aggregationsRepository,
|
||||||
blobsRepository = blobsRepository,
|
blobsRepository = blobsRepository,
|
||||||
@@ -684,10 +684,10 @@ class L1DependentApp(
|
|||||||
aggregationSubmitter = AggregationSubmitterImpl(
|
aggregationSubmitter = AggregationSubmitterImpl(
|
||||||
lineaRollup = lineaSmartContractClientForFinalization,
|
lineaRollup = lineaSmartContractClientForFinalization,
|
||||||
gasPriceCapProvider = gasPriceCapProviderForFinalization,
|
gasPriceCapProvider = gasPriceCapProviderForFinalization,
|
||||||
aggregationSubmittedEventConsumer = EventDispatcher(submittedFinalizationConsumers)
|
aggregationSubmittedEventConsumer = EventDispatcher(submittedFinalizationConsumers),
|
||||||
),
|
),
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
clock = Clock.System
|
clock = Clock.System,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -702,13 +702,13 @@ class L1DependentApp(
|
|||||||
rpcClient = httpJsonRpcClientFactory.createWithLoadBalancing(
|
rpcClient = httpJsonRpcClientFactory.createWithLoadBalancing(
|
||||||
endpoints = tracesCounterV2Config.endpoints.toSet(),
|
endpoints = tracesCounterV2Config.endpoints.toSet(),
|
||||||
maxInflightRequestsPerClient = tracesCounterV2Config.requestLimitPerEndpoint,
|
maxInflightRequestsPerClient = tracesCounterV2Config.requestLimitPerEndpoint,
|
||||||
log = tracesCountersLog
|
log = tracesCountersLog,
|
||||||
),
|
),
|
||||||
config = TracesGeneratorJsonRpcClientV2.Config(
|
config = TracesGeneratorJsonRpcClientV2.Config(
|
||||||
expectedTracesApiVersion = expectedTracesApiVersionV2
|
expectedTracesApiVersion = expectedTracesApiVersionV2,
|
||||||
),
|
),
|
||||||
retryConfig = tracesCounterV2Config.requestRetryConfig,
|
retryConfig = tracesCounterV2Config.requestRetryConfig,
|
||||||
log = tracesCountersLog
|
log = tracesCountersLog,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -721,13 +721,13 @@ class L1DependentApp(
|
|||||||
rpcClient = httpJsonRpcClientFactory.createWithLoadBalancing(
|
rpcClient = httpJsonRpcClientFactory.createWithLoadBalancing(
|
||||||
endpoints = tracesConflationConfigV2.endpoints.toSet(),
|
endpoints = tracesConflationConfigV2.endpoints.toSet(),
|
||||||
maxInflightRequestsPerClient = tracesConflationConfigV2.requestLimitPerEndpoint,
|
maxInflightRequestsPerClient = tracesConflationConfigV2.requestLimitPerEndpoint,
|
||||||
log = tracesConflationLog
|
log = tracesConflationLog,
|
||||||
),
|
),
|
||||||
config = TracesGeneratorJsonRpcClientV2.Config(
|
config = TracesGeneratorJsonRpcClientV2.Config(
|
||||||
expectedTracesApiVersion = expectedTracesApiVersionV2
|
expectedTracesApiVersion = expectedTracesApiVersionV2,
|
||||||
),
|
),
|
||||||
retryConfig = tracesConflationConfigV2.requestRetryConfig,
|
retryConfig = tracesConflationConfigV2.requestRetryConfig,
|
||||||
log = tracesConflationLog
|
log = tracesConflationLog,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -738,7 +738,7 @@ class L1DependentApp(
|
|||||||
category = LineaMetricsCategory.BATCH,
|
category = LineaMetricsCategory.BATCH,
|
||||||
name = "proven.highest.block.number",
|
name = "proven.highest.block.number",
|
||||||
description = "Highest proven batch execution block number",
|
description = "Highest proven batch execution block number",
|
||||||
measurementSupplier = highestProvenBatchTracker
|
measurementSupplier = highestProvenBatchTracker,
|
||||||
)
|
)
|
||||||
highestProvenBatchTracker
|
highestProvenBatchTracker
|
||||||
}
|
}
|
||||||
@@ -746,12 +746,12 @@ class L1DependentApp(
|
|||||||
val batchProofHandler = SimpleCompositeSafeFutureHandler(
|
val batchProofHandler = SimpleCompositeSafeFutureHandler(
|
||||||
listOf(
|
listOf(
|
||||||
maxProvenBatchCache,
|
maxProvenBatchCache,
|
||||||
BatchProofHandlerImpl(batchesRepository)::acceptNewBatch
|
BatchProofHandlerImpl(batchesRepository)::acceptNewBatch,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
val executionProverClient: ExecutionProverClientV2 = proverClientFactory.executionProverClient(
|
val executionProverClient: ExecutionProverClientV2 = proverClientFactory.executionProverClient(
|
||||||
tracesVersion = configs.traces.rawExecutionTracesVersion,
|
tracesVersion = configs.traces.rawExecutionTracesVersion,
|
||||||
stateManagerVersion = configs.stateManager.version
|
stateManagerVersion = configs.stateManager.version,
|
||||||
)
|
)
|
||||||
|
|
||||||
val proofGeneratingConflationHandlerImpl = ProofGeneratingConflationHandlerImpl(
|
val proofGeneratingConflationHandlerImpl = ProofGeneratingConflationHandlerImpl(
|
||||||
@@ -762,15 +762,15 @@ class L1DependentApp(
|
|||||||
web3jClient = l2Web3jClient,
|
web3jClient = l2Web3jClient,
|
||||||
requestRetryConfig = linea.domain.RetryConfig(
|
requestRetryConfig = linea.domain.RetryConfig(
|
||||||
backoffDelay = 1.seconds,
|
backoffDelay = 1.seconds,
|
||||||
failuresWarningThreshold = 3u
|
failuresWarningThreshold = 3u,
|
||||||
),
|
),
|
||||||
vertx = vertx
|
vertx = vertx,
|
||||||
),
|
),
|
||||||
messageServiceAddress = configs.l2.messageServiceAddress
|
messageServiceAddress = configs.l2.messageServiceAddress,
|
||||||
),
|
),
|
||||||
batchProofHandler = batchProofHandler,
|
batchProofHandler = batchProofHandler,
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
config = ProofGeneratingConflationHandlerImpl.Config(5.seconds)
|
config = ProofGeneratingConflationHandlerImpl.Config(5.seconds),
|
||||||
)
|
)
|
||||||
|
|
||||||
val highestConflationTracker = HighestConflationTracker(lastProcessedBlockNumber)
|
val highestConflationTracker = HighestConflationTracker(lastProcessedBlockNumber)
|
||||||
@@ -778,12 +778,12 @@ class L1DependentApp(
|
|||||||
category = LineaMetricsCategory.CONFLATION,
|
category = LineaMetricsCategory.CONFLATION,
|
||||||
name = "last.block.number",
|
name = "last.block.number",
|
||||||
description = "Last conflated block number",
|
description = "Last conflated block number",
|
||||||
measurementSupplier = highestConflationTracker
|
measurementSupplier = highestConflationTracker,
|
||||||
)
|
)
|
||||||
val conflationsCounter = metricsFacade.createCounter(
|
val conflationsCounter = metricsFacade.createCounter(
|
||||||
category = LineaMetricsCategory.CONFLATION,
|
category = LineaMetricsCategory.CONFLATION,
|
||||||
name = "counter",
|
name = "counter",
|
||||||
description = "Counter of new conflations"
|
description = "Counter of new conflations",
|
||||||
)
|
)
|
||||||
|
|
||||||
SimpleCompositeSafeFutureHandler(
|
SimpleCompositeSafeFutureHandler(
|
||||||
@@ -793,8 +793,8 @@ class L1DependentApp(
|
|||||||
{
|
{
|
||||||
conflationsCounter.increment()
|
conflationsCounter.increment()
|
||||||
SafeFuture.COMPLETE
|
SafeFuture.COMPLETE
|
||||||
}
|
},
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -804,20 +804,20 @@ class L1DependentApp(
|
|||||||
conflationService = conflationService,
|
conflationService = conflationService,
|
||||||
tracesCountersClient = tracesCountersClient,
|
tracesCountersClient = tracesCountersClient,
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
encoder = BlockRLPEncoder
|
encoder = BlockRLPEncoder,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val lastProvenBlockNumberProvider = run {
|
private val lastProvenBlockNumberProvider = run {
|
||||||
val lastProvenConsecutiveBatchBlockNumberProvider = BatchesRepoBasedLastProvenBlockNumberProvider(
|
val lastProvenConsecutiveBatchBlockNumberProvider = BatchesRepoBasedLastProvenBlockNumberProvider(
|
||||||
lastProcessedBlockNumber.toLong(),
|
lastProcessedBlockNumber.toLong(),
|
||||||
batchesRepository
|
batchesRepository,
|
||||||
)
|
)
|
||||||
metricsFacade.createGauge(
|
metricsFacade.createGauge(
|
||||||
category = LineaMetricsCategory.BATCH,
|
category = LineaMetricsCategory.BATCH,
|
||||||
name = "proven.highest.consecutive.block.number",
|
name = "proven.highest.consecutive.block.number",
|
||||||
description = "Highest proven consecutive execution batch block number",
|
description = "Highest proven consecutive execution batch block number",
|
||||||
measurementSupplier = { lastProvenConsecutiveBatchBlockNumberProvider.getLastKnownProvenBlockNumber() }
|
measurementSupplier = { lastProvenConsecutiveBatchBlockNumberProvider.getLastKnownProvenBlockNumber() },
|
||||||
)
|
)
|
||||||
lastProvenConsecutiveBatchBlockNumberProvider
|
lastProvenConsecutiveBatchBlockNumberProvider
|
||||||
}
|
}
|
||||||
@@ -837,8 +837,8 @@ class L1DependentApp(
|
|||||||
// We need to add 1 to l2InclusiveBlockNumberToStopAndFlushAggregation because conflation calculator requires
|
// We need to add 1 to l2InclusiveBlockNumberToStopAndFlushAggregation because conflation calculator requires
|
||||||
// block_number = l2InclusiveBlockNumberToStopAndFlushAggregation + 1 to trigger conflation at
|
// block_number = l2InclusiveBlockNumberToStopAndFlushAggregation + 1 to trigger conflation at
|
||||||
// l2InclusiveBlockNumberToStopAndFlushAggregation
|
// l2InclusiveBlockNumberToStopAndFlushAggregation
|
||||||
lastL2BlockNumberToProcessInclusive = configs.l2InclusiveBlockNumberToStopAndFlushAggregation?.let { it + 1uL }
|
lastL2BlockNumberToProcessInclusive = configs.l2InclusiveBlockNumberToStopAndFlushAggregation?.let { it + 1uL },
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
blockCreationMonitor
|
blockCreationMonitor
|
||||||
}
|
}
|
||||||
@@ -847,7 +847,7 @@ class L1DependentApp(
|
|||||||
val l1BasedLastFinalizedBlockProvider = L1BasedLastFinalizedBlockProvider(
|
val l1BasedLastFinalizedBlockProvider = L1BasedLastFinalizedBlockProvider(
|
||||||
vertx,
|
vertx,
|
||||||
lineaRollupClient,
|
lineaRollupClient,
|
||||||
configs.conflation.consistentNumberOfBlocksOnL1ToWait.toUInt()
|
configs.conflation.consistentNumberOfBlocksOnL1ToWait.toUInt(),
|
||||||
)
|
)
|
||||||
return l1BasedLastFinalizedBlockProvider.getLastFinalizedBlock()
|
return l1BasedLastFinalizedBlockProvider.getLastFinalizedBlock()
|
||||||
}
|
}
|
||||||
@@ -867,12 +867,12 @@ class L1DependentApp(
|
|||||||
l2HighestBlockTag = configs.messageAnchoring.l2HighestBlockTag,
|
l2HighestBlockTag = configs.messageAnchoring.l2HighestBlockTag,
|
||||||
anchoringTickInterval = configs.messageAnchoring.anchoringTickInterval,
|
anchoringTickInterval = configs.messageAnchoring.anchoringTickInterval,
|
||||||
messageQueueCapacity = configs.messageAnchoring.messageQueueCapacity,
|
messageQueueCapacity = configs.messageAnchoring.messageQueueCapacity,
|
||||||
maxMessagesToAnchorPerL2Transaction = configs.messageAnchoring.maxMessagesToAnchorPerL2Transaction
|
maxMessagesToAnchorPerL2Transaction = configs.messageAnchoring.maxMessagesToAnchorPerL2Transaction,
|
||||||
),
|
),
|
||||||
l1EthApiClient = createEthApiClient(
|
l1EthApiClient = createEthApiClient(
|
||||||
web3jClient = l1Web3jClient,
|
web3jClient = l1Web3jClient,
|
||||||
requestRetryConfig = null,
|
requestRetryConfig = null,
|
||||||
vertx = vertx
|
vertx = vertx,
|
||||||
),
|
),
|
||||||
l2MessageService = Web3JL2MessageServiceSmartContractClient.create(
|
l2MessageService = Web3JL2MessageServiceSmartContractClient.create(
|
||||||
web3jClient = l2Web3jClient,
|
web3jClient = l2Web3jClient,
|
||||||
@@ -883,8 +883,8 @@ class L1DependentApp(
|
|||||||
feeHistoryRewardPercentile = configs.l2.feeHistoryRewardPercentile,
|
feeHistoryRewardPercentile = configs.l2.feeHistoryRewardPercentile,
|
||||||
transactionManager = l2TransactionManager,
|
transactionManager = l2TransactionManager,
|
||||||
smartContractErrors = smartContractErrors,
|
smartContractErrors = smartContractErrors,
|
||||||
smartContractDeploymentBlockNumber = configs.l2.messageServiceDeploymentBlockNumber
|
smartContractDeploymentBlockNumber = configs.l2.messageServiceDeploymentBlockNumber,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
DisabledLongRunningService
|
DisabledLongRunningService
|
||||||
@@ -897,7 +897,7 @@ class L1DependentApp(
|
|||||||
httpJsonRpcClientFactory = httpJsonRpcClientFactory,
|
httpJsonRpcClientFactory = httpJsonRpcClientFactory,
|
||||||
l1Web3jClient = l1Web3jClient,
|
l1Web3jClient = l1Web3jClient,
|
||||||
l1Web3jService = l1Web3jService,
|
l1Web3jService = l1Web3jService,
|
||||||
config = configs.l2NetworkGasPricingService
|
config = configs.l2NetworkGasPricingService,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
@@ -916,16 +916,16 @@ class L1DependentApp(
|
|||||||
val l1FeeHistoryWeb3jBlobExtClient = Web3jBlobExtended(
|
val l1FeeHistoryWeb3jBlobExtClient = Web3jBlobExtended(
|
||||||
HttpService(
|
HttpService(
|
||||||
configs.l1DynamicGasPriceCapService.feeHistoryFetcher.endpoint?.toString()
|
configs.l1DynamicGasPriceCapService.feeHistoryFetcher.endpoint?.toString()
|
||||||
?: configs.l1.ethFeeHistoryEndpoint.toString()
|
?: configs.l1.ethFeeHistoryEndpoint.toString(),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
val l1FeeHistoryFetcher: GasPriceCapFeeHistoryFetcher = GasPriceCapFeeHistoryFetcherImpl(
|
val l1FeeHistoryFetcher: GasPriceCapFeeHistoryFetcher = GasPriceCapFeeHistoryFetcherImpl(
|
||||||
web3jService = l1FeeHistoryWeb3jBlobExtClient,
|
web3jService = l1FeeHistoryWeb3jBlobExtClient,
|
||||||
config = GasPriceCapFeeHistoryFetcherImpl.Config(
|
config = GasPriceCapFeeHistoryFetcherImpl.Config(
|
||||||
maxBlockCount = configs.l1DynamicGasPriceCapService.feeHistoryFetcher.maxBlockCount,
|
maxBlockCount = configs.l1DynamicGasPriceCapService.feeHistoryFetcher.maxBlockCount,
|
||||||
rewardPercentiles = configs.l1DynamicGasPriceCapService.feeHistoryFetcher.rewardPercentiles
|
rewardPercentiles = configs.l1DynamicGasPriceCapService.feeHistoryFetcher.rewardPercentiles,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
FeeHistoryCachingService(
|
FeeHistoryCachingService(
|
||||||
@@ -939,12 +939,12 @@ class L1DependentApp(
|
|||||||
feeHistoryStoragePeriodInBlocks = feeHistoryStoragePeriodInBlocks,
|
feeHistoryStoragePeriodInBlocks = feeHistoryStoragePeriodInBlocks,
|
||||||
feeHistoryWindowInBlocks = feeHistoryPercentileWindowInBlocks,
|
feeHistoryWindowInBlocks = feeHistoryPercentileWindowInBlocks,
|
||||||
numOfBlocksBeforeLatest =
|
numOfBlocksBeforeLatest =
|
||||||
configs.l1DynamicGasPriceCapService.feeHistoryFetcher.numOfBlocksBeforeLatest
|
configs.l1DynamicGasPriceCapService.feeHistoryFetcher.numOfBlocksBeforeLatest,
|
||||||
),
|
),
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
web3jClient = l1Web3jClient,
|
web3jClient = l1Web3jClient,
|
||||||
feeHistoryFetcher = l1FeeHistoryFetcher,
|
feeHistoryFetcher = l1FeeHistoryFetcher,
|
||||||
feeHistoriesRepository = l1FeeHistoriesRepository
|
feeHistoriesRepository = l1FeeHistoriesRepository,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
DisabledLongRunningService
|
DisabledLongRunningService
|
||||||
@@ -955,7 +955,7 @@ class L1DependentApp(
|
|||||||
category = LineaMetricsCategory.AGGREGATION,
|
category = LineaMetricsCategory.AGGREGATION,
|
||||||
name = "highest.accepted.block.number",
|
name = "highest.accepted.block.number",
|
||||||
description = "Highest finalized accepted end block number",
|
description = "Highest finalized accepted end block number",
|
||||||
measurementSupplier = it
|
measurementSupplier = it,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -967,11 +967,11 @@ class L1DependentApp(
|
|||||||
"finalized records cleanup" to RecordsCleanupFinalizationHandler(
|
"finalized records cleanup" to RecordsCleanupFinalizationHandler(
|
||||||
batchesRepository = batchesRepository,
|
batchesRepository = batchesRepository,
|
||||||
blobsRepository = blobsRepository,
|
blobsRepository = blobsRepository,
|
||||||
aggregationsRepository = aggregationsRepository
|
aggregationsRepository = aggregationsRepository,
|
||||||
),
|
),
|
||||||
"highest_accepted_finalization_on_l1" to FinalizationHandler { update: FinalizationMonitor.FinalizationUpdate ->
|
"highest_accepted_finalization_on_l1" to FinalizationHandler { update: FinalizationMonitor.FinalizationUpdate ->
|
||||||
highestAcceptedFinalizationTracker(update.blockNumber)
|
highestAcceptedFinalizationTracker(update.blockNumber)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
.forEach { (handlerName, handler) ->
|
.forEach { (handlerName, handler) ->
|
||||||
l1FinalizationMonitor.addFinalizationHandler(handlerName, handler)
|
l1FinalizationMonitor.addFinalizationHandler(handlerName, handler)
|
||||||
@@ -984,7 +984,7 @@ class L1DependentApp(
|
|||||||
lastConsecutiveAggregatedBlockNumber = lastConsecutiveAggregatedBlockNumber,
|
lastConsecutiveAggregatedBlockNumber = lastConsecutiveAggregatedBlockNumber,
|
||||||
batchesRepository = batchesRepository,
|
batchesRepository = batchesRepository,
|
||||||
blobsRepository = blobsRepository,
|
blobsRepository = blobsRepository,
|
||||||
aggregationsRepository = aggregationsRepository
|
aggregationsRepository = aggregationsRepository,
|
||||||
)
|
)
|
||||||
.thenCompose { l1FinalizationMonitor.start() }
|
.thenCompose { l1FinalizationMonitor.start() }
|
||||||
.thenCompose { l1FinalizationHandlerForShomeiRpc.start() }
|
.thenCompose { l1FinalizationHandlerForShomeiRpc.start() }
|
||||||
@@ -1016,7 +1016,7 @@ class L1DependentApp(
|
|||||||
blockCreationMonitor.stop(),
|
blockCreationMonitor.stop(),
|
||||||
deadlineConflationCalculatorRunnerOld.stop(),
|
deadlineConflationCalculatorRunnerOld.stop(),
|
||||||
deadlineConflationCalculatorRunnerNew.stop(),
|
deadlineConflationCalculatorRunnerNew.stop(),
|
||||||
blobCompressionProofCoordinator.stop()
|
blobCompressionProofCoordinator.stop(),
|
||||||
)
|
)
|
||||||
.thenCompose { SafeFuture.fromRunnable { l1Web3jClient.shutdown() } }
|
.thenCompose { SafeFuture.fromRunnable { l1Web3jClient.shutdown() } }
|
||||||
.thenApply { log.info("L1App Stopped") }
|
.thenApply { log.info("L1App Stopped") }
|
||||||
@@ -1029,7 +1029,7 @@ class L1DependentApp(
|
|||||||
lastConsecutiveAggregatedBlockNumber: ULong,
|
lastConsecutiveAggregatedBlockNumber: ULong,
|
||||||
batchesRepository: BatchesRepository,
|
batchesRepository: BatchesRepository,
|
||||||
blobsRepository: BlobsRepository,
|
blobsRepository: BlobsRepository,
|
||||||
aggregationsRepository: AggregationsRepository
|
aggregationsRepository: AggregationsRepository,
|
||||||
): SafeFuture<*> {
|
): SafeFuture<*> {
|
||||||
val blockNumberInclusiveToDeleteFrom = lastProcessedBlockNumber + 1u
|
val blockNumberInclusiveToDeleteFrom = lastProcessedBlockNumber + 1u
|
||||||
val cleanupBatches = batchesRepository.deleteBatchesAfterBlockNumber(blockNumberInclusiveToDeleteFrom.toLong())
|
val cleanupBatches = batchesRepository.deleteBatchesAfterBlockNumber(blockNumberInclusiveToDeleteFrom.toLong())
|
||||||
@@ -1046,7 +1046,7 @@ class L1DependentApp(
|
|||||||
*/
|
*/
|
||||||
fun resumeConflationFrom(
|
fun resumeConflationFrom(
|
||||||
aggregationsRepository: AggregationsRepository,
|
aggregationsRepository: AggregationsRepository,
|
||||||
lastFinalizedBlock: ULong
|
lastFinalizedBlock: ULong,
|
||||||
): SafeFuture<ULong> {
|
): SafeFuture<ULong> {
|
||||||
return aggregationsRepository
|
return aggregationsRepository
|
||||||
.findConsecutiveProvenBlobs(lastFinalizedBlock.toLong() + 1)
|
.findConsecutiveProvenBlobs(lastFinalizedBlock.toLong() + 1)
|
||||||
@@ -1061,7 +1061,7 @@ class L1DependentApp(
|
|||||||
|
|
||||||
fun resumeAggregationFrom(
|
fun resumeAggregationFrom(
|
||||||
aggregationsRepository: AggregationsRepository,
|
aggregationsRepository: AggregationsRepository,
|
||||||
lastFinalizedBlock: ULong
|
lastFinalizedBlock: ULong,
|
||||||
): SafeFuture<ULong> {
|
): SafeFuture<ULong> {
|
||||||
return aggregationsRepository
|
return aggregationsRepository
|
||||||
.findHighestConsecutiveEndBlockNumber(lastFinalizedBlock.toLong() + 1)
|
.findHighestConsecutiveEndBlockNumber(lastFinalizedBlock.toLong() + 1)
|
||||||
@@ -1075,7 +1075,7 @@ class L1DependentApp(
|
|||||||
httpJsonRpcClientFactory: VertxHttpJsonRpcClientFactory,
|
httpJsonRpcClientFactory: VertxHttpJsonRpcClientFactory,
|
||||||
lineaRollupClient: LineaRollupSmartContractClientReadOnly,
|
lineaRollupClient: LineaRollupSmartContractClientReadOnly,
|
||||||
l2Web3jClient: Web3j,
|
l2Web3jClient: Web3j,
|
||||||
vertx: Vertx
|
vertx: Vertx,
|
||||||
): LongRunningService {
|
): LongRunningService {
|
||||||
if (type2StateProofProviderConfig == null ||
|
if (type2StateProofProviderConfig == null ||
|
||||||
type2StateProofProviderConfig.disabled ||
|
type2StateProofProviderConfig.disabled ||
|
||||||
@@ -1091,7 +1091,7 @@ class L1DependentApp(
|
|||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
rpcClient = httpJsonRpcClientFactory.create(it, log = log),
|
rpcClient = httpJsonRpcClientFactory.create(it, log = log),
|
||||||
retryConfig = type2StateProofProviderConfig.requestRetryConfig,
|
retryConfig = type2StateProofProviderConfig.requestRetryConfig,
|
||||||
log = log
|
log = log,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1103,16 +1103,16 @@ class L1DependentApp(
|
|||||||
config =
|
config =
|
||||||
FinalizationMonitorImpl.Config(
|
FinalizationMonitorImpl.Config(
|
||||||
pollingInterval = type2StateProofProviderConfig.l1PollingInterval.toKotlinDuration(),
|
pollingInterval = type2StateProofProviderConfig.l1PollingInterval.toKotlinDuration(),
|
||||||
l1QueryBlockTag = type2StateProofProviderConfig.l1QueryBlockTag
|
l1QueryBlockTag = type2StateProofProviderConfig.l1QueryBlockTag,
|
||||||
),
|
),
|
||||||
contract = lineaRollupClient,
|
contract = lineaRollupClient,
|
||||||
l2Client = l2Web3jClient,
|
l2Client = l2Web3jClient,
|
||||||
vertx = vertx
|
vertx = vertx,
|
||||||
)
|
)
|
||||||
|
|
||||||
l1FinalizationMonitor.addFinalizationHandler("type 2 state proof provider finalization updates", {
|
l1FinalizationMonitor.addFinalizationHandler("type 2 state proof provider finalization updates", {
|
||||||
finalizedBlockNotifier.updateFinalizedBlock(
|
finalizedBlockNotifier.updateFinalizedBlock(
|
||||||
BlockNumberAndHash(it.blockNumber, it.blockHash.toArray())
|
BlockNumberAndHash(it.blockNumber, it.blockHash.toArray()),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -28,12 +28,12 @@ class L2NetworkGasPricingService(
|
|||||||
httpJsonRpcClientFactory: VertxHttpJsonRpcClientFactory,
|
httpJsonRpcClientFactory: VertxHttpJsonRpcClientFactory,
|
||||||
l1Web3jClient: Web3j,
|
l1Web3jClient: Web3j,
|
||||||
l1Web3jService: Web3jBlobExtended,
|
l1Web3jService: Web3jBlobExtended,
|
||||||
config: Config
|
config: Config,
|
||||||
) : LongRunningService {
|
) : LongRunningService {
|
||||||
data class LegacyGasPricingCalculatorConfig(
|
data class LegacyGasPricingCalculatorConfig(
|
||||||
val transactionCostCalculatorConfig: TransactionCostCalculator.Config?,
|
val transactionCostCalculatorConfig: TransactionCostCalculator.Config?,
|
||||||
val naiveGasPricingCalculatorConfig: GasUsageRatioWeightedAverageFeesCalculator.Config?,
|
val naiveGasPricingCalculatorConfig: GasUsageRatioWeightedAverageFeesCalculator.Config?,
|
||||||
val legacyGasPricingCalculatorBounds: BoundableFeeCalculator.Config
|
val legacyGasPricingCalculatorBounds: BoundableFeeCalculator.Config,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Config(
|
data class Config(
|
||||||
@@ -46,23 +46,23 @@ class L2NetworkGasPricingService(
|
|||||||
val variableFeesCalculatorConfig: VariableFeesCalculator.Config,
|
val variableFeesCalculatorConfig: VariableFeesCalculator.Config,
|
||||||
val variableFeesCalculatorBounds: BoundableFeeCalculator.Config,
|
val variableFeesCalculatorBounds: BoundableFeeCalculator.Config,
|
||||||
val extraDataCalculatorConfig: MinerExtraDataV1CalculatorImpl.Config,
|
val extraDataCalculatorConfig: MinerExtraDataV1CalculatorImpl.Config,
|
||||||
val extraDataUpdaterConfig: ExtraDataV1UpdaterImpl.Config
|
val extraDataUpdaterConfig: ExtraDataV1UpdaterImpl.Config,
|
||||||
)
|
)
|
||||||
private val log = LogManager.getLogger(this::class.java)
|
private val log = LogManager.getLogger(this::class.java)
|
||||||
|
|
||||||
private val gasPricingFeesFetcher: FeesFetcher = FeeHistoryFetcherImpl(
|
private val gasPricingFeesFetcher: FeesFetcher = FeeHistoryFetcherImpl(
|
||||||
l1Web3jClient,
|
l1Web3jClient,
|
||||||
l1Web3jService,
|
l1Web3jService,
|
||||||
config.feeHistoryFetcherConfig
|
config.feeHistoryFetcherConfig,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val boundedVariableCostCalculator = run {
|
private val boundedVariableCostCalculator = run {
|
||||||
val variableCostCalculator = VariableFeesCalculator(
|
val variableCostCalculator = VariableFeesCalculator(
|
||||||
config.variableFeesCalculatorConfig
|
config.variableFeesCalculatorConfig,
|
||||||
)
|
)
|
||||||
BoundableFeeCalculator(
|
BoundableFeeCalculator(
|
||||||
config = config.variableFeesCalculatorBounds,
|
config = config.variableFeesCalculatorBounds,
|
||||||
feesCalculator = variableCostCalculator
|
feesCalculator = variableCostCalculator,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,12 +71,12 @@ class L2NetworkGasPricingService(
|
|||||||
TransactionCostCalculator(boundedVariableCostCalculator, config.legacy.transactionCostCalculatorConfig)
|
TransactionCostCalculator(boundedVariableCostCalculator, config.legacy.transactionCostCalculatorConfig)
|
||||||
} else {
|
} else {
|
||||||
GasUsageRatioWeightedAverageFeesCalculator(
|
GasUsageRatioWeightedAverageFeesCalculator(
|
||||||
config.legacy.naiveGasPricingCalculatorConfig!!
|
config.legacy.naiveGasPricingCalculatorConfig!!,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
BoundableFeeCalculator(
|
BoundableFeeCalculator(
|
||||||
config.legacy.legacyGasPricingCalculatorBounds,
|
config.legacy.legacyGasPricingCalculatorBounds,
|
||||||
baseCalculator
|
baseCalculator,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ class L2NetworkGasPricingService(
|
|||||||
if (config.jsonRpcGasPriceUpdaterConfig != null) {
|
if (config.jsonRpcGasPriceUpdaterConfig != null) {
|
||||||
val l2SetGasPriceUpdater: GasPriceUpdater = GasPriceUpdaterImpl(
|
val l2SetGasPriceUpdater: GasPriceUpdater = GasPriceUpdaterImpl(
|
||||||
httpJsonRpcClientFactory = httpJsonRpcClientFactory,
|
httpJsonRpcClientFactory = httpJsonRpcClientFactory,
|
||||||
config = config.jsonRpcGasPriceUpdaterConfig
|
config = config.jsonRpcGasPriceUpdaterConfig,
|
||||||
)
|
)
|
||||||
|
|
||||||
MinMineableFeesPricerService(
|
MinMineableFeesPricerService(
|
||||||
@@ -92,7 +92,7 @@ class L2NetworkGasPricingService(
|
|||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
feesFetcher = gasPricingFeesFetcher,
|
feesFetcher = gasPricingFeesFetcher,
|
||||||
feesCalculator = legacyGasPricingCalculator,
|
feesCalculator = legacyGasPricingCalculator,
|
||||||
gasPriceUpdater = l2SetGasPriceUpdater
|
gasPriceUpdater = l2SetGasPriceUpdater,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
@@ -106,12 +106,12 @@ class L2NetworkGasPricingService(
|
|||||||
minerExtraDataCalculatorImpl = MinerExtraDataV1CalculatorImpl(
|
minerExtraDataCalculatorImpl = MinerExtraDataV1CalculatorImpl(
|
||||||
config = config.extraDataCalculatorConfig,
|
config = config.extraDataCalculatorConfig,
|
||||||
variableFeesCalculator = boundedVariableCostCalculator,
|
variableFeesCalculator = boundedVariableCostCalculator,
|
||||||
legacyFeesCalculator = legacyGasPricingCalculator
|
legacyFeesCalculator = legacyGasPricingCalculator,
|
||||||
),
|
),
|
||||||
extraDataUpdater = ExtraDataV1UpdaterImpl(
|
extraDataUpdater = ExtraDataV1UpdaterImpl(
|
||||||
httpJsonRpcClientFactory = httpJsonRpcClientFactory,
|
httpJsonRpcClientFactory = httpJsonRpcClientFactory,
|
||||||
config = config.extraDataUpdaterConfig
|
config = config.extraDataUpdaterConfig,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
@@ -128,7 +128,7 @@ class L2NetworkGasPricingService(
|
|||||||
override fun stop(): CompletableFuture<Unit> {
|
override fun stop(): CompletableFuture<Unit> {
|
||||||
return SafeFuture.allOf(
|
return SafeFuture.allOf(
|
||||||
minMineableFeesPricerService?.stop() ?: SafeFuture.completedFuture(Unit),
|
minMineableFeesPricerService?.stop() ?: SafeFuture.completedFuture(Unit),
|
||||||
extraDataPricerService?.stop() ?: SafeFuture.completedFuture(Unit)
|
extraDataPricerService?.stop() ?: SafeFuture.completedFuture(Unit),
|
||||||
)
|
)
|
||||||
.thenApply { }
|
.thenApply { }
|
||||||
.thenPeek {
|
.thenPeek {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class L1BasedLastFinalizedBlockProvider(
|
|||||||
private val lineaRollupSmartContractClient: LineaRollupSmartContractClientReadOnly,
|
private val lineaRollupSmartContractClient: LineaRollupSmartContractClientReadOnly,
|
||||||
private val consistentNumberOfBlocksOnL1: UInt,
|
private val consistentNumberOfBlocksOnL1: UInt,
|
||||||
private val numberOfRetries: UInt = Int.MAX_VALUE.toUInt(),
|
private val numberOfRetries: UInt = Int.MAX_VALUE.toUInt(),
|
||||||
private val pollingInterval: Duration = 2.seconds
|
private val pollingInterval: Duration = 2.seconds,
|
||||||
) : LastFinalizedBlockProvider {
|
) : LastFinalizedBlockProvider {
|
||||||
private val log: Logger = LogManager.getLogger(this::class.java)
|
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",
|
"Rollup finalized block updated from {} to {}, waiting {} blocks for confirmation",
|
||||||
lastObservedBlock.get(),
|
lastObservedBlock.get(),
|
||||||
lastPolledBlockNumber,
|
lastPolledBlockNumber,
|
||||||
consistentNumberOfBlocksOnL1
|
consistentNumberOfBlocksOnL1,
|
||||||
)
|
)
|
||||||
numberOfObservations.set(1)
|
numberOfObservations.set(1)
|
||||||
lastObservedBlock.set(lastPolledBlockNumber)
|
lastObservedBlock.set(lastPolledBlockNumber)
|
||||||
@@ -54,10 +54,10 @@ class L1BasedLastFinalizedBlockProvider(
|
|||||||
vertx,
|
vertx,
|
||||||
maxRetries = numberOfRetries.toInt(),
|
maxRetries = numberOfRetries.toInt(),
|
||||||
backoffDelay = pollingInterval,
|
backoffDelay = pollingInterval,
|
||||||
stopRetriesPredicate = isConsistentEnough
|
stopRetriesPredicate = isConsistentEnough,
|
||||||
) {
|
) {
|
||||||
lineaRollupSmartContractClient.finalizedL2BlockNumber(
|
lineaRollupSmartContractClient.finalizedL2BlockNumber(
|
||||||
blockParameter = BlockParameter.Tag.LATEST
|
blockParameter = BlockParameter.Tag.LATEST,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,14 +20,14 @@ class BlockParameterDecoder : Decoder<BlockParameter> {
|
|||||||
BlockParameter.parse(node.value)
|
BlockParameter.parse(node.value)
|
||||||
}.fold(
|
}.fold(
|
||||||
{ it.valid() },
|
{ it.valid() },
|
||||||
{ ConfigFailure.DecodeError(node, type).invalid() }
|
{ ConfigFailure.DecodeError(node, type).invalid() },
|
||||||
)
|
)
|
||||||
|
|
||||||
is LongNode -> runCatching {
|
is LongNode -> runCatching {
|
||||||
BlockParameter.fromNumber(node.value)
|
BlockParameter.fromNumber(node.value)
|
||||||
}.fold(
|
}.fold(
|
||||||
{ it.valid() },
|
{ it.valid() },
|
||||||
{ ConfigFailure.DecodeError(node, type).invalid() }
|
{ ConfigFailure.DecodeError(node, type).invalid() },
|
||||||
)
|
)
|
||||||
|
|
||||||
else -> ConfigFailure.DecodeError(node, type).invalid()
|
else -> ConfigFailure.DecodeError(node, type).invalid()
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import kotlin.time.toJavaDuration
|
|||||||
import kotlin.time.toKotlinDuration
|
import kotlin.time.toKotlinDuration
|
||||||
|
|
||||||
data class ApiConfig(
|
data class ApiConfig(
|
||||||
val observabilityPort: UInt
|
val observabilityPort: UInt,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class ConflationConfig(
|
data class ConflationConfig(
|
||||||
@@ -42,7 +42,7 @@ data class ConflationConfig(
|
|||||||
private var _smartContractErrors: SmartContractErrors?,
|
private var _smartContractErrors: SmartContractErrors?,
|
||||||
val fetchBlocksLimit: Int,
|
val fetchBlocksLimit: Int,
|
||||||
@ConfigAlias("conflation-target-end-block-numbers")
|
@ConfigAlias("conflation-target-end-block-numbers")
|
||||||
private val _conflationTargetEndBlockNumbers: List<Long> = emptyList()
|
private val _conflationTargetEndBlockNumbers: List<Long> = emptyList(),
|
||||||
) {
|
) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -84,7 +84,7 @@ data class RequestRetryConfigTomlFriendly(
|
|||||||
override val maxRetries: Int? = null,
|
override val maxRetries: Int? = null,
|
||||||
override val timeout: Duration? = null,
|
override val timeout: Duration? = null,
|
||||||
override val backoffDelay: Duration = 1.milliseconds.toJavaDuration(),
|
override val backoffDelay: Duration = 1.milliseconds.toJavaDuration(),
|
||||||
val failuresWarningThreshold: Int = 0
|
val failuresWarningThreshold: Int = 0,
|
||||||
) : RetryConfig {
|
) : RetryConfig {
|
||||||
init {
|
init {
|
||||||
maxRetries?.also {
|
maxRetries?.also {
|
||||||
@@ -105,25 +105,25 @@ data class RequestRetryConfigTomlFriendly(
|
|||||||
maxRetries = maxRetries?.toUInt(),
|
maxRetries = maxRetries?.toUInt(),
|
||||||
timeout = timeout?.toKotlinDuration(),
|
timeout = timeout?.toKotlinDuration(),
|
||||||
backoffDelay = backoffDelay.toKotlinDuration(),
|
backoffDelay = backoffDelay.toKotlinDuration(),
|
||||||
failuresWarningThreshold = failuresWarningThreshold.toUInt()
|
failuresWarningThreshold = failuresWarningThreshold.toUInt(),
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val asDomain: linea.domain.RetryConfig = linea.domain.RetryConfig(
|
internal val asDomain: linea.domain.RetryConfig = linea.domain.RetryConfig(
|
||||||
maxRetries = maxRetries?.toUInt(),
|
maxRetries = maxRetries?.toUInt(),
|
||||||
timeout = timeout?.toKotlinDuration(),
|
timeout = timeout?.toKotlinDuration(),
|
||||||
backoffDelay = backoffDelay.toKotlinDuration(),
|
backoffDelay = backoffDelay.toKotlinDuration(),
|
||||||
failuresWarningThreshold = failuresWarningThreshold.toUInt()
|
failuresWarningThreshold = failuresWarningThreshold.toUInt(),
|
||||||
)
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun endlessRetry(
|
fun endlessRetry(
|
||||||
backoffDelay: Duration,
|
backoffDelay: Duration,
|
||||||
failuresWarningThreshold: Int
|
failuresWarningThreshold: Int,
|
||||||
) = RequestRetryConfigTomlFriendly(
|
) = RequestRetryConfigTomlFriendly(
|
||||||
maxRetries = null,
|
maxRetries = null,
|
||||||
timeout = null,
|
timeout = null,
|
||||||
backoffDelay = backoffDelay,
|
backoffDelay = backoffDelay,
|
||||||
failuresWarningThreshold = failuresWarningThreshold
|
failuresWarningThreshold = failuresWarningThreshold,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,7 +131,7 @@ data class RequestRetryConfigTomlFriendly(
|
|||||||
data class PersistenceRetryConfig(
|
data class PersistenceRetryConfig(
|
||||||
override val maxRetries: Int? = null,
|
override val maxRetries: Int? = null,
|
||||||
override val backoffDelay: Duration = 1.seconds.toJavaDuration(),
|
override val backoffDelay: Duration = 1.seconds.toJavaDuration(),
|
||||||
override val timeout: Duration? = 10.minutes.toJavaDuration()
|
override val timeout: Duration? = 10.minutes.toJavaDuration(),
|
||||||
) : RetryConfig
|
) : RetryConfig
|
||||||
|
|
||||||
internal interface RequestRetryConfigurable {
|
internal interface RequestRetryConfigurable {
|
||||||
@@ -144,7 +144,7 @@ data class BlobCompressionConfig(
|
|||||||
val blobSizeLimit: Int,
|
val blobSizeLimit: Int,
|
||||||
@ConfigAlias("batches-limit")
|
@ConfigAlias("batches-limit")
|
||||||
private val _batchesLimit: Int? = null,
|
private val _batchesLimit: Int? = null,
|
||||||
val handlerPollingInterval: Duration
|
val handlerPollingInterval: Duration,
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
_batchesLimit?.also {
|
_batchesLimit?.also {
|
||||||
@@ -163,7 +163,7 @@ data class AggregationConfig(
|
|||||||
val deadlineCheckInterval: Duration,
|
val deadlineCheckInterval: Duration,
|
||||||
val aggregationSizeMultipleOf: Int = 1,
|
val aggregationSizeMultipleOf: Int = 1,
|
||||||
@ConfigAlias("target-end-blocks")
|
@ConfigAlias("target-end-blocks")
|
||||||
private val _targetEndBlocks: List<Long> = emptyList()
|
private val _targetEndBlocks: List<Long> = emptyList(),
|
||||||
) {
|
) {
|
||||||
val targetEndBlocks: List<ULong> = _targetEndBlocks.map { it.toULong() }
|
val targetEndBlocks: List<ULong> = _targetEndBlocks.map { it.toULong() }
|
||||||
|
|
||||||
@@ -177,12 +177,12 @@ data class TracesConfig(
|
|||||||
val blobCompressorVersion: BlobCompressorVersion,
|
val blobCompressorVersion: BlobCompressorVersion,
|
||||||
val expectedTracesApiVersionV2: String,
|
val expectedTracesApiVersionV2: String,
|
||||||
val countersV2: FunctionalityEndpoint,
|
val countersV2: FunctionalityEndpoint,
|
||||||
val conflationV2: FunctionalityEndpoint
|
val conflationV2: FunctionalityEndpoint,
|
||||||
) {
|
) {
|
||||||
data class FunctionalityEndpoint(
|
data class FunctionalityEndpoint(
|
||||||
val endpoints: List<URL>,
|
val endpoints: List<URL>,
|
||||||
val requestLimitPerEndpoint: UInt,
|
val requestLimitPerEndpoint: UInt,
|
||||||
override val requestRetry: RequestRetryConfigTomlFriendly
|
override val requestRetry: RequestRetryConfigTomlFriendly,
|
||||||
) : RequestRetryConfigurable {
|
) : RequestRetryConfigurable {
|
||||||
init {
|
init {
|
||||||
require(requestLimitPerEndpoint > 0u) { "requestLimitPerEndpoint must be greater than 0" }
|
require(requestLimitPerEndpoint > 0u) { "requestLimitPerEndpoint must be greater than 0" }
|
||||||
@@ -194,7 +194,7 @@ data class StateManagerClientConfig(
|
|||||||
val version: String,
|
val version: String,
|
||||||
val endpoints: List<URL>,
|
val endpoints: List<URL>,
|
||||||
val requestLimitPerEndpoint: UInt,
|
val requestLimitPerEndpoint: UInt,
|
||||||
override val requestRetry: RequestRetryConfigTomlFriendly
|
override val requestRetry: RequestRetryConfigTomlFriendly,
|
||||||
) : RequestRetryConfigurable {
|
) : RequestRetryConfigurable {
|
||||||
init {
|
init {
|
||||||
require(requestLimitPerEndpoint > 0u) { "requestLimitPerEndpoint must be greater than 0" }
|
require(requestLimitPerEndpoint > 0u) { "requestLimitPerEndpoint must be greater than 0" }
|
||||||
@@ -210,7 +210,7 @@ data class BlobSubmissionConfig(
|
|||||||
val maxBlobsToSubmitPerTick: Int = maxBlobsToReturn,
|
val maxBlobsToSubmitPerTick: Int = maxBlobsToReturn,
|
||||||
val targetBlobsToSendPerTransaction: Int = 9,
|
val targetBlobsToSendPerTransaction: Int = 9,
|
||||||
val useEthEstimateGas: Boolean = false,
|
val useEthEstimateGas: Boolean = false,
|
||||||
override var disabled: Boolean = false
|
override var disabled: Boolean = false,
|
||||||
) : FeatureToggleable {
|
) : FeatureToggleable {
|
||||||
init {
|
init {
|
||||||
require(maxBlobsToReturn > 0) { "maxBlobsToReturn must be greater than 0" }
|
require(maxBlobsToReturn > 0) { "maxBlobsToReturn must be greater than 0" }
|
||||||
@@ -226,7 +226,7 @@ data class AggregationFinalizationConfig(
|
|||||||
val maxAggregationsToFinalizePerTick: Int,
|
val maxAggregationsToFinalizePerTick: Int,
|
||||||
val proofSubmissionDelay: Duration,
|
val proofSubmissionDelay: Duration,
|
||||||
val useEthEstimateGas: Boolean = false,
|
val useEthEstimateGas: Boolean = false,
|
||||||
override var disabled: Boolean = false
|
override var disabled: Boolean = false,
|
||||||
) : FeatureToggleable {
|
) : FeatureToggleable {
|
||||||
init {
|
init {
|
||||||
require(maxAggregationsToFinalizePerTick > 0) {
|
require(maxAggregationsToFinalizePerTick > 0) {
|
||||||
@@ -243,7 +243,7 @@ data class DatabaseConfig(
|
|||||||
val schema: String,
|
val schema: String,
|
||||||
val readPoolSize: Int,
|
val readPoolSize: Int,
|
||||||
val readPipeliningLimit: Int,
|
val readPipeliningLimit: Int,
|
||||||
val transactionalPoolSize: Int
|
val transactionalPoolSize: Int,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class L1Config(
|
data class L1Config(
|
||||||
@@ -268,7 +268,7 @@ data class L1Config(
|
|||||||
val blockTime: Duration = Duration.parse("PT12S"),
|
val blockTime: Duration = Duration.parse("PT12S"),
|
||||||
@ConfigAlias("eth-fee-history-endpoint") private val _ethFeeHistoryEndpoint: URL?,
|
@ConfigAlias("eth-fee-history-endpoint") private val _ethFeeHistoryEndpoint: URL?,
|
||||||
@ConfigAlias("genesis-state-root-hash") private val _genesisStateRootHash: String,
|
@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
|
val ethFeeHistoryEndpoint: URL
|
||||||
get() = _ethFeeHistoryEndpoint ?: rpcEndpoint
|
get() = _ethFeeHistoryEndpoint ?: rpcEndpoint
|
||||||
@@ -303,7 +303,7 @@ data class L2Config(
|
|||||||
val lastHashSearchWindow: UInt,
|
val lastHashSearchWindow: UInt,
|
||||||
val anchoringReceiptPollingInterval: Duration,
|
val anchoringReceiptPollingInterval: Duration,
|
||||||
val maxReceiptRetries: UInt,
|
val maxReceiptRetries: UInt,
|
||||||
val newBlockPollingInterval: Duration
|
val newBlockPollingInterval: Duration,
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
messageServiceAddress.assertIsValidAddress("messageServiceAddress")
|
messageServiceAddress.assertIsValidAddress("messageServiceAddress")
|
||||||
@@ -313,11 +313,11 @@ data class L2Config(
|
|||||||
data class SignerConfig(
|
data class SignerConfig(
|
||||||
val type: Type,
|
val type: Type,
|
||||||
val web3signer: Web3SignerConfig?,
|
val web3signer: Web3SignerConfig?,
|
||||||
val web3j: Web3jConfig?
|
val web3j: Web3jConfig?,
|
||||||
) {
|
) {
|
||||||
enum class Type {
|
enum class Type {
|
||||||
Web3j,
|
Web3j,
|
||||||
Web3Signer
|
Web3Signer,
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -334,14 +334,14 @@ data class SignerConfig(
|
|||||||
}
|
}
|
||||||
|
|
||||||
data class Web3jConfig(
|
data class Web3jConfig(
|
||||||
val privateKey: Masked
|
val privateKey: Masked,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Web3SignerConfig(
|
data class Web3SignerConfig(
|
||||||
val endpoint: String,
|
val endpoint: String,
|
||||||
val maxPoolSize: UInt,
|
val maxPoolSize: UInt,
|
||||||
val keepAlive: Boolean,
|
val keepAlive: Boolean,
|
||||||
val publicKey: String
|
val publicKey: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
interface FeatureToggleable {
|
interface FeatureToggleable {
|
||||||
@@ -354,7 +354,7 @@ data class L1DynamicGasPriceCapServiceConfig(
|
|||||||
val gasPriceCapCalculation: GasPriceCapCalculation,
|
val gasPriceCapCalculation: GasPriceCapCalculation,
|
||||||
val feeHistoryFetcher: FeeHistoryFetcher,
|
val feeHistoryFetcher: FeeHistoryFetcher,
|
||||||
val feeHistoryStorage: FeeHistoryStorage,
|
val feeHistoryStorage: FeeHistoryStorage,
|
||||||
override var disabled: Boolean = false
|
override var disabled: Boolean = false,
|
||||||
) : FeatureToggleable {
|
) : FeatureToggleable {
|
||||||
data class GasPriceCapCalculation(
|
data class GasPriceCapCalculation(
|
||||||
val adjustmentConstant: UInt,
|
val adjustmentConstant: UInt,
|
||||||
@@ -366,7 +366,7 @@ data class L1DynamicGasPriceCapServiceConfig(
|
|||||||
val gasPriceCapsCheckCoefficient: Double,
|
val gasPriceCapsCheckCoefficient: Double,
|
||||||
val historicBaseFeePerBlobGasLowerBound: ULong,
|
val historicBaseFeePerBlobGasLowerBound: ULong,
|
||||||
val historicAvgRewardConstant: ULong?,
|
val historicAvgRewardConstant: ULong?,
|
||||||
val timeOfDayMultipliers: TimeOfDayMultipliers?
|
val timeOfDayMultipliers: TimeOfDayMultipliers?,
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
timeOfDayMultipliers?.also {
|
timeOfDayMultipliers?.also {
|
||||||
@@ -385,7 +385,7 @@ data class L1DynamicGasPriceCapServiceConfig(
|
|||||||
require(timeOfDayMultiplier.value > 0.0) {
|
require(timeOfDayMultiplier.value > 0.0) {
|
||||||
throw IllegalStateException(
|
throw IllegalStateException(
|
||||||
"Each multiplier in timeOfDayMultipliers must be greater than 0.0." +
|
"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(
|
data class FeeHistoryStorage(
|
||||||
val storagePeriod: Duration
|
val storagePeriod: Duration,
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
require(storagePeriod <= MAX_FEE_HISTORIES_STORAGE_PERIOD.toJavaDuration()) {
|
require(storagePeriod <= MAX_FEE_HISTORIES_STORAGE_PERIOD.toJavaDuration()) {
|
||||||
@@ -418,12 +418,12 @@ data class L1DynamicGasPriceCapServiceConfig(
|
|||||||
val maxBlockCount: UInt,
|
val maxBlockCount: UInt,
|
||||||
val rewardPercentiles: List<Double>,
|
val rewardPercentiles: List<Double>,
|
||||||
val numOfBlocksBeforeLatest: UInt = 4U,
|
val numOfBlocksBeforeLatest: UInt = 4U,
|
||||||
val endpoint: URL?
|
val endpoint: URL?,
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
require(
|
require(
|
||||||
maxBlockCount > 0U &&
|
maxBlockCount > 0U &&
|
||||||
maxBlockCount <= MAX_FEE_HISTORY_BLOCK_COUNT
|
maxBlockCount <= MAX_FEE_HISTORY_BLOCK_COUNT,
|
||||||
) {
|
) {
|
||||||
"maxBlockCount must be greater than 0 and " +
|
"maxBlockCount must be greater than 0 and " +
|
||||||
"less than or equal to $MAX_FEE_HISTORY_BLOCK_COUNT"
|
"less than or equal to $MAX_FEE_HISTORY_BLOCK_COUNT"
|
||||||
@@ -431,7 +431,7 @@ data class L1DynamicGasPriceCapServiceConfig(
|
|||||||
|
|
||||||
require(
|
require(
|
||||||
rewardPercentiles.isNotEmpty() &&
|
rewardPercentiles.isNotEmpty() &&
|
||||||
rewardPercentiles.size <= MAX_REWARD_PERCENTILES_SIZE
|
rewardPercentiles.size <= MAX_REWARD_PERCENTILES_SIZE,
|
||||||
) {
|
) {
|
||||||
"rewardPercentiles must be a non-empty list with " +
|
"rewardPercentiles must be a non-empty list with " +
|
||||||
"maximum length as $MAX_REWARD_PERCENTILES_SIZE."
|
"maximum length as $MAX_REWARD_PERCENTILES_SIZE."
|
||||||
@@ -459,7 +459,7 @@ data class L1DynamicGasPriceCapServiceConfig(
|
|||||||
|
|
||||||
require(
|
require(
|
||||||
gasPriceCapCalculation.gasFeePercentileWindow
|
gasPriceCapCalculation.gasFeePercentileWindow
|
||||||
>= gasPriceCapCalculation.gasFeePercentileWindowLeeway
|
>= gasPriceCapCalculation.gasFeePercentileWindowLeeway,
|
||||||
) {
|
) {
|
||||||
"gasFeePercentileWindow must be at least same length as" +
|
"gasFeePercentileWindow must be at least same length as" +
|
||||||
" gasFeePercentileWindowLeeway=${gasPriceCapCalculation.gasFeePercentileWindowLeeway}." +
|
" gasFeePercentileWindowLeeway=${gasPriceCapCalculation.gasFeePercentileWindowLeeway}." +
|
||||||
@@ -483,7 +483,7 @@ data class Type2StateProofProviderConfig(
|
|||||||
val endpoints: List<URL>,
|
val endpoints: List<URL>,
|
||||||
val l1QueryBlockTag: BlockParameter.Tag = BlockParameter.Tag.LATEST,
|
val l1QueryBlockTag: BlockParameter.Tag = BlockParameter.Tag.LATEST,
|
||||||
val l1PollingInterval: Duration = Duration.ofSeconds(12),
|
val l1PollingInterval: Duration = Duration.ofSeconds(12),
|
||||||
override val requestRetry: RequestRetryConfigTomlFriendly
|
override val requestRetry: RequestRetryConfigTomlFriendly,
|
||||||
) : FeatureToggleable, RequestRetryConfigurable
|
) : FeatureToggleable, RequestRetryConfigurable
|
||||||
|
|
||||||
data class TracesLimitsV2ConfigFile(val tracesLimits: Map<TracingModuleV2, UInt>)
|
data class TracesLimitsV2ConfigFile(val tracesLimits: Map<TracingModuleV2, UInt>)
|
||||||
@@ -515,7 +515,7 @@ data class CoordinatorConfigTomlDto(
|
|||||||
val l2NetworkGasPricing: L2NetworkGasPricingTomlDto,
|
val l2NetworkGasPricing: L2NetworkGasPricingTomlDto,
|
||||||
val l1DynamicGasPriceCapService: L1DynamicGasPriceCapServiceConfig,
|
val l1DynamicGasPriceCapService: L1DynamicGasPriceCapServiceConfig,
|
||||||
val testL1Disabled: Boolean = false,
|
val testL1Disabled: Boolean = false,
|
||||||
val prover: ProverConfigTomlDto
|
val prover: ProverConfigTomlDto,
|
||||||
) {
|
) {
|
||||||
fun reified(): CoordinatorConfig = CoordinatorConfig(
|
fun reified(): CoordinatorConfig = CoordinatorConfig(
|
||||||
l2InclusiveBlockNumberToStopAndFlushAggregation = l2InclusiveBlockNumberToStopAndFlushAggregation,
|
l2InclusiveBlockNumberToStopAndFlushAggregation = l2InclusiveBlockNumberToStopAndFlushAggregation,
|
||||||
@@ -537,13 +537,13 @@ data class CoordinatorConfigTomlDto(
|
|||||||
l2Signer = l2Signer,
|
l2Signer = l2Signer,
|
||||||
messageAnchoring = messageAnchoring.reified(
|
messageAnchoring = messageAnchoring.reified(
|
||||||
l1DefaultEndpoint = l1.rpcEndpoint,
|
l1DefaultEndpoint = l1.rpcEndpoint,
|
||||||
l2DefaultEndpoint = l2.rpcEndpoint
|
l2DefaultEndpoint = l2.rpcEndpoint,
|
||||||
),
|
),
|
||||||
l2NetworkGasPricingService =
|
l2NetworkGasPricingService =
|
||||||
if (testL1Disabled || l2NetworkGasPricing.disabled) null else l2NetworkGasPricing.reified(),
|
if (testL1Disabled || l2NetworkGasPricing.disabled) null else l2NetworkGasPricing.reified(),
|
||||||
l1DynamicGasPriceCapService = l1DynamicGasPriceCapService,
|
l1DynamicGasPriceCapService = l1DynamicGasPriceCapService,
|
||||||
testL1Disabled = testL1Disabled,
|
testL1Disabled = testL1Disabled,
|
||||||
proversConfig = prover.reified()
|
proversConfig = prover.reified(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -569,7 +569,7 @@ data class CoordinatorConfig(
|
|||||||
val l2NetworkGasPricingService: L2NetworkGasPricingService.Config?,
|
val l2NetworkGasPricingService: L2NetworkGasPricingService.Config?,
|
||||||
val l1DynamicGasPriceCapService: L1DynamicGasPriceCapServiceConfig,
|
val l1DynamicGasPriceCapService: L1DynamicGasPriceCapServiceConfig,
|
||||||
val testL1Disabled: Boolean = false,
|
val testL1Disabled: Boolean = false,
|
||||||
val proversConfig: ProversConfig
|
val proversConfig: ProversConfig,
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
if (l2InclusiveBlockNumberToStopAndFlushAggregation != null) {
|
if (l2InclusiveBlockNumberToStopAndFlushAggregation != null) {
|
||||||
@@ -583,7 +583,7 @@ data class CoordinatorConfig(
|
|||||||
|
|
||||||
require(
|
require(
|
||||||
blobCompression.batchesLimit == null ||
|
blobCompression.batchesLimit == null ||
|
||||||
blobCompression.batchesLimit!! < proofAggregation.aggregationProofsLimit.toUInt()
|
blobCompression.batchesLimit!! < proofAggregation.aggregationProofsLimit.toUInt(),
|
||||||
) {
|
) {
|
||||||
"[blob-compression].batchesLimit=${blobCompression.batchesLimit} must be less than " +
|
"[blob-compression].batchesLimit=${blobCompression.batchesLimit} must be less than " +
|
||||||
"[proof-aggregation].aggregationProofsLimit=${proofAggregation.aggregationProofsLimit}"
|
"[proof-aggregation].aggregationProofsLimit=${proofAggregation.aggregationProofsLimit}"
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import kotlin.time.toKotlinDuration
|
|||||||
data class SampleTransactionGasPricingTomlDto(
|
data class SampleTransactionGasPricingTomlDto(
|
||||||
val plainTransferCostMultiplier: Double = 1.0,
|
val plainTransferCostMultiplier: Double = 1.0,
|
||||||
val compressedTxSize: Int = 125,
|
val compressedTxSize: Int = 125,
|
||||||
val expectedGas: Int = 21000
|
val expectedGas: Int = 21000,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class LegacyGasPricingTomlDto(
|
data class LegacyGasPricingTomlDto(
|
||||||
@@ -28,11 +28,11 @@ data class LegacyGasPricingTomlDto(
|
|||||||
val naiveGasPricing: NaiveGasPricingTomlDto?,
|
val naiveGasPricing: NaiveGasPricingTomlDto?,
|
||||||
val sampleTransactionGasPricing: SampleTransactionGasPricingTomlDto = SampleTransactionGasPricingTomlDto(),
|
val sampleTransactionGasPricing: SampleTransactionGasPricingTomlDto = SampleTransactionGasPricingTomlDto(),
|
||||||
val gasPriceUpperBound: ULong,
|
val gasPriceUpperBound: ULong,
|
||||||
val gasPriceLowerBound: ULong
|
val gasPriceLowerBound: ULong,
|
||||||
) {
|
) {
|
||||||
enum class Type {
|
enum class Type {
|
||||||
Naive,
|
Naive,
|
||||||
SampleTransaction
|
SampleTransaction,
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -49,7 +49,7 @@ data class LegacyGasPricingTomlDto(
|
|||||||
data class NaiveGasPricingTomlDto(
|
data class NaiveGasPricingTomlDto(
|
||||||
val baseFeeCoefficient: Double,
|
val baseFeeCoefficient: Double,
|
||||||
val priorityFeeCoefficient: Double,
|
val priorityFeeCoefficient: Double,
|
||||||
val baseFeeBlobCoefficient: Double
|
val baseFeeBlobCoefficient: Double,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class VariableCostPricingTomlDto(
|
data class VariableCostPricingTomlDto(
|
||||||
@@ -57,7 +57,7 @@ data class VariableCostPricingTomlDto(
|
|||||||
val legacyFeesMultiplier: Double,
|
val legacyFeesMultiplier: Double,
|
||||||
val margin: Double,
|
val margin: Double,
|
||||||
val variableCostUpperBound: ULong,
|
val variableCostUpperBound: ULong,
|
||||||
val variableCostLowerBound: ULong
|
val variableCostLowerBound: ULong,
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
require(variableCostUpperBound >= variableCostLowerBound) {
|
require(variableCostUpperBound >= variableCostLowerBound) {
|
||||||
@@ -69,7 +69,7 @@ data class VariableCostPricingTomlDto(
|
|||||||
data class JsonRpcPricingPropagationTomlDto(
|
data class JsonRpcPricingPropagationTomlDto(
|
||||||
override var disabled: Boolean = false,
|
override var disabled: Boolean = false,
|
||||||
val gethGasPriceUpdateRecipients: List<URL>,
|
val gethGasPriceUpdateRecipients: List<URL>,
|
||||||
val besuGasPriceUpdateRecipients: List<URL>
|
val besuGasPriceUpdateRecipients: List<URL>,
|
||||||
) : FeatureToggleable {
|
) : FeatureToggleable {
|
||||||
init {
|
init {
|
||||||
require(disabled || (gethGasPriceUpdateRecipients.isNotEmpty() || besuGasPriceUpdateRecipients.isNotEmpty())) {
|
require(disabled || (gethGasPriceUpdateRecipients.isNotEmpty() || besuGasPriceUpdateRecipients.isNotEmpty())) {
|
||||||
@@ -81,7 +81,7 @@ data class JsonRpcPricingPropagationTomlDto(
|
|||||||
|
|
||||||
data class ExtraDataPricingPropagationTomlDto(
|
data class ExtraDataPricingPropagationTomlDto(
|
||||||
override var disabled: Boolean = false,
|
override var disabled: Boolean = false,
|
||||||
val extraDataUpdateRecipient: URL
|
val extraDataUpdateRecipient: URL,
|
||||||
) : FeatureToggleable
|
) : FeatureToggleable
|
||||||
|
|
||||||
data class L2NetworkGasPricingTomlDto(
|
data class L2NetworkGasPricingTomlDto(
|
||||||
@@ -99,7 +99,7 @@ data class L2NetworkGasPricingTomlDto(
|
|||||||
val legacy: LegacyGasPricingTomlDto,
|
val legacy: LegacyGasPricingTomlDto,
|
||||||
val variableCostPricing: VariableCostPricingTomlDto,
|
val variableCostPricing: VariableCostPricingTomlDto,
|
||||||
val jsonRpcPricingPropagation: JsonRpcPricingPropagationTomlDto?,
|
val jsonRpcPricingPropagation: JsonRpcPricingPropagationTomlDto?,
|
||||||
val extraDataPricingPropagation: ExtraDataPricingPropagationTomlDto
|
val extraDataPricingPropagation: ExtraDataPricingPropagationTomlDto,
|
||||||
) : FeatureToggleable, RequestRetryConfigurable {
|
) : FeatureToggleable, RequestRetryConfigurable {
|
||||||
init {
|
init {
|
||||||
require(feeHistoryBlockCount > 0) { "feeHistoryBlockCount must be greater than 0" }
|
require(feeHistoryBlockCount > 0) { "feeHistoryBlockCount must be greater than 0" }
|
||||||
@@ -124,13 +124,13 @@ data class L2NetworkGasPricingTomlDto(
|
|||||||
priorityFeeCoefficient = legacy.naiveGasPricing.priorityFeeCoefficient,
|
priorityFeeCoefficient = legacy.naiveGasPricing.priorityFeeCoefficient,
|
||||||
baseFeeBlobCoefficient = legacy.naiveGasPricing.baseFeeBlobCoefficient,
|
baseFeeBlobCoefficient = legacy.naiveGasPricing.baseFeeBlobCoefficient,
|
||||||
blobSubmissionExpectedExecutionGas = blobSubmissionExpectedExecutionGas,
|
blobSubmissionExpectedExecutionGas = blobSubmissionExpectedExecutionGas,
|
||||||
expectedBlobGas = l1BlobGas
|
expectedBlobGas = l1BlobGas,
|
||||||
),
|
),
|
||||||
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
|
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
|
||||||
legacy.gasPriceUpperBound.toDouble(),
|
legacy.gasPriceUpperBound.toDouble(),
|
||||||
legacy.gasPriceLowerBound.toDouble(),
|
legacy.gasPriceLowerBound.toDouble(),
|
||||||
0.0
|
0.0,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,14 +140,14 @@ data class L2NetworkGasPricingTomlDto(
|
|||||||
sampleTransactionCostMultiplier = legacy.sampleTransactionGasPricing.plainTransferCostMultiplier,
|
sampleTransactionCostMultiplier = legacy.sampleTransactionGasPricing.plainTransferCostMultiplier,
|
||||||
fixedCostWei = variableCostPricing.gasPriceFixedCost,
|
fixedCostWei = variableCostPricing.gasPriceFixedCost,
|
||||||
compressedTxSize = legacy.sampleTransactionGasPricing.compressedTxSize,
|
compressedTxSize = legacy.sampleTransactionGasPricing.compressedTxSize,
|
||||||
expectedGas = legacy.sampleTransactionGasPricing.expectedGas
|
expectedGas = legacy.sampleTransactionGasPricing.expectedGas,
|
||||||
),
|
),
|
||||||
naiveGasPricingCalculatorConfig = null,
|
naiveGasPricingCalculatorConfig = null,
|
||||||
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
|
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
|
||||||
legacy.gasPriceUpperBound.toDouble(),
|
legacy.gasPriceUpperBound.toDouble(),
|
||||||
legacy.gasPriceLowerBound.toDouble(),
|
legacy.gasPriceLowerBound.toDouble(),
|
||||||
0.0
|
0.0,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -155,7 +155,7 @@ data class L2NetworkGasPricingTomlDto(
|
|||||||
GasPriceUpdaterImpl.Config(
|
GasPriceUpdaterImpl.Config(
|
||||||
gethEndpoints = jsonRpcPricingPropagation.gethGasPriceUpdateRecipients,
|
gethEndpoints = jsonRpcPricingPropagation.gethGasPriceUpdateRecipients,
|
||||||
besuEndPoints = jsonRpcPricingPropagation.besuGasPriceUpdateRecipients,
|
besuEndPoints = jsonRpcPricingPropagation.besuGasPriceUpdateRecipients,
|
||||||
retryConfig = requestRetryConfig
|
retryConfig = requestRetryConfig,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
@@ -163,7 +163,7 @@ data class L2NetworkGasPricingTomlDto(
|
|||||||
return L2NetworkGasPricingService.Config(
|
return L2NetworkGasPricingService.Config(
|
||||||
feeHistoryFetcherConfig = FeeHistoryFetcherImpl.Config(
|
feeHistoryFetcherConfig = FeeHistoryFetcherImpl.Config(
|
||||||
feeHistoryBlockCount = feeHistoryBlockCount.toUInt(),
|
feeHistoryBlockCount = feeHistoryBlockCount.toUInt(),
|
||||||
feeHistoryRewardPercentile = feeHistoryRewardPercentile
|
feeHistoryRewardPercentile = feeHistoryRewardPercentile,
|
||||||
),
|
),
|
||||||
legacy = legacyGasPricingConfig,
|
legacy = legacyGasPricingConfig,
|
||||||
jsonRpcGasPriceUpdaterConfig = gasPriceUpdaterConfig,
|
jsonRpcGasPriceUpdaterConfig = gasPriceUpdaterConfig,
|
||||||
@@ -174,21 +174,21 @@ data class L2NetworkGasPricingTomlDto(
|
|||||||
blobSubmissionExpectedExecutionGas = blobSubmissionExpectedExecutionGas.toUInt(),
|
blobSubmissionExpectedExecutionGas = blobSubmissionExpectedExecutionGas.toUInt(),
|
||||||
bytesPerDataSubmission = l1BlobGas.toUInt(),
|
bytesPerDataSubmission = l1BlobGas.toUInt(),
|
||||||
expectedBlobGas = bytesPerDataSubmission.toUInt(),
|
expectedBlobGas = bytesPerDataSubmission.toUInt(),
|
||||||
margin = variableCostPricing.margin
|
margin = variableCostPricing.margin,
|
||||||
),
|
),
|
||||||
variableFeesCalculatorBounds = BoundableFeeCalculator.Config(
|
variableFeesCalculatorBounds = BoundableFeeCalculator.Config(
|
||||||
feeUpperBound = variableCostPricing.variableCostUpperBound.toDouble(),
|
feeUpperBound = variableCostPricing.variableCostUpperBound.toDouble(),
|
||||||
feeLowerBound = variableCostPricing.variableCostLowerBound.toDouble(),
|
feeLowerBound = variableCostPricing.variableCostLowerBound.toDouble(),
|
||||||
feeMargin = 0.0
|
feeMargin = 0.0,
|
||||||
),
|
),
|
||||||
extraDataCalculatorConfig = MinerExtraDataV1CalculatorImpl.Config(
|
extraDataCalculatorConfig = MinerExtraDataV1CalculatorImpl.Config(
|
||||||
fixedCostInKWei = variableCostPricing.gasPriceFixedCost.toKWeiUInt(),
|
fixedCostInKWei = variableCostPricing.gasPriceFixedCost.toKWeiUInt(),
|
||||||
ethGasPriceMultiplier = variableCostPricing.legacyFeesMultiplier
|
ethGasPriceMultiplier = variableCostPricing.legacyFeesMultiplier,
|
||||||
),
|
),
|
||||||
extraDataUpdaterConfig = ExtraDataV1UpdaterImpl.Config(
|
extraDataUpdaterConfig = ExtraDataV1UpdaterImpl.Config(
|
||||||
extraDataPricingPropagation.extraDataUpdateRecipient,
|
extraDataPricingPropagation.extraDataUpdateRecipient,
|
||||||
requestRetryConfig
|
requestRetryConfig,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ data class MessageAnchoringConfigTomlDto(
|
|||||||
val l1HighestBlockTag: BlockParameter = BlockParameter.Tag.FINALIZED,
|
val l1HighestBlockTag: BlockParameter = BlockParameter.Tag.FINALIZED,
|
||||||
val l1RequestRetries: RequestRetryConfigTomlFriendly = RequestRetryConfigTomlFriendly.endlessRetry(
|
val l1RequestRetries: RequestRetryConfigTomlFriendly = RequestRetryConfigTomlFriendly.endlessRetry(
|
||||||
backoffDelay = 1.seconds.toJavaDuration(),
|
backoffDelay = 1.seconds.toJavaDuration(),
|
||||||
failuresWarningThreshold = 3
|
failuresWarningThreshold = 3,
|
||||||
),
|
),
|
||||||
val l1EventPollingInterval: Duration = 12.seconds.toJavaDuration(),
|
val l1EventPollingInterval: Duration = 12.seconds.toJavaDuration(),
|
||||||
val l1EventPollingTimeout: Duration = 6.seconds.toJavaDuration(),
|
val l1EventPollingTimeout: Duration = 6.seconds.toJavaDuration(),
|
||||||
@@ -24,11 +24,11 @@ data class MessageAnchoringConfigTomlDto(
|
|||||||
val l2HighestBlockTag: BlockParameter = BlockParameter.Tag.LATEST,
|
val l2HighestBlockTag: BlockParameter = BlockParameter.Tag.LATEST,
|
||||||
val l2RequestRetries: RequestRetryConfigTomlFriendly = RequestRetryConfigTomlFriendly.endlessRetry(
|
val l2RequestRetries: RequestRetryConfigTomlFriendly = RequestRetryConfigTomlFriendly.endlessRetry(
|
||||||
backoffDelay = 1.seconds.toJavaDuration(),
|
backoffDelay = 1.seconds.toJavaDuration(),
|
||||||
failuresWarningThreshold = 3
|
failuresWarningThreshold = 3,
|
||||||
),
|
),
|
||||||
val anchoringTickInterval: Duration = 2.seconds.toJavaDuration(),
|
val anchoringTickInterval: Duration = 2.seconds.toJavaDuration(),
|
||||||
val messageQueueCapacity: Int = 10_000,
|
val messageQueueCapacity: Int = 10_000,
|
||||||
val maxMessagesToAnchorPerL2Transaction: Int = 100
|
val maxMessagesToAnchorPerL2Transaction: Int = 100,
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
require(messageQueueCapacity > 0) {
|
require(messageQueueCapacity > 0) {
|
||||||
@@ -56,7 +56,7 @@ data class MessageAnchoringConfigTomlDto(
|
|||||||
|
|
||||||
fun reified(
|
fun reified(
|
||||||
l1DefaultEndpoint: URL,
|
l1DefaultEndpoint: URL,
|
||||||
l2DefaultEndpoint: URL
|
l2DefaultEndpoint: URL,
|
||||||
): MessageAnchoringConfig {
|
): MessageAnchoringConfig {
|
||||||
return MessageAnchoringConfig(
|
return MessageAnchoringConfig(
|
||||||
disabled = disabled,
|
disabled = disabled,
|
||||||
@@ -72,7 +72,7 @@ data class MessageAnchoringConfigTomlDto(
|
|||||||
l1EventSearchBlockChunk = l1EventSearchBlockChunk.toUInt(),
|
l1EventSearchBlockChunk = l1EventSearchBlockChunk.toUInt(),
|
||||||
anchoringTickInterval = anchoringTickInterval.toKotlinDuration(),
|
anchoringTickInterval = anchoringTickInterval.toKotlinDuration(),
|
||||||
messageQueueCapacity = messageQueueCapacity.toUInt(),
|
messageQueueCapacity = messageQueueCapacity.toUInt(),
|
||||||
maxMessagesToAnchorPerL2Transaction = maxMessagesToAnchorPerL2Transaction.toUInt()
|
maxMessagesToAnchorPerL2Transaction = maxMessagesToAnchorPerL2Transaction.toUInt(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,5 +91,5 @@ data class MessageAnchoringConfig(
|
|||||||
val l1EventSearchBlockChunk: UInt,
|
val l1EventSearchBlockChunk: UInt,
|
||||||
val anchoringTickInterval: kotlin.time.Duration,
|
val anchoringTickInterval: kotlin.time.Duration,
|
||||||
val messageQueueCapacity: UInt,
|
val messageQueueCapacity: UInt,
|
||||||
val maxMessagesToAnchorPerL2Transaction: UInt
|
val maxMessagesToAnchorPerL2Transaction: UInt,
|
||||||
) : FeatureToggleable
|
) : FeatureToggleable
|
||||||
|
|||||||
@@ -19,13 +19,13 @@ data class ProverConfigTomlDto(
|
|||||||
val execution: FileSystemTomlDto,
|
val execution: FileSystemTomlDto,
|
||||||
val blobCompression: FileSystemTomlDto,
|
val blobCompression: FileSystemTomlDto,
|
||||||
val proofAggregation: FileSystemTomlDto,
|
val proofAggregation: FileSystemTomlDto,
|
||||||
val new: ProverConfigTomlDto? = null
|
val new: ProverConfigTomlDto? = null,
|
||||||
) {
|
) {
|
||||||
private fun asProverConfig(): ProverConfig {
|
private fun asProverConfig(): ProverConfig {
|
||||||
return ProverConfig(
|
return ProverConfig(
|
||||||
execution = execution.toDomain(),
|
execution = execution.toDomain(),
|
||||||
blobCompression = blobCompression.toDomain(),
|
blobCompression = blobCompression.toDomain(),
|
||||||
proofAggregation = proofAggregation.toDomain()
|
proofAggregation = proofAggregation.toDomain(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ data class ProverConfigTomlDto(
|
|||||||
return ProversConfig(
|
return ProversConfig(
|
||||||
proverA = this.asProverConfig(),
|
proverA = this.asProverConfig(),
|
||||||
switchBlockNumberInclusive = new?.switchBlockNumberInclusive?.toULong(),
|
switchBlockNumberInclusive = new?.switchBlockNumberInclusive?.toULong(),
|
||||||
proverB = new?.asProverConfig()
|
proverB = new?.asProverConfig(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ data class FileSystemTomlDto(
|
|||||||
internal var fsInprogressRequestWritingSuffix: String?,
|
internal var fsInprogressRequestWritingSuffix: String?,
|
||||||
internal var fsInprogressProvingSuffixPattern: String?,
|
internal var fsInprogressProvingSuffixPattern: String?,
|
||||||
internal var fsPollingInterval: Duration?,
|
internal var fsPollingInterval: Duration?,
|
||||||
internal var fsPollingTimeout: Duration?
|
internal var fsPollingTimeout: Duration?,
|
||||||
) {
|
) {
|
||||||
internal fun reifyWithRootDefaults(rootConfig: ProverConfigTomlDto) {
|
internal fun reifyWithRootDefaults(rootConfig: ProverConfigTomlDto) {
|
||||||
fsInprogressRequestWritingSuffix = fsInprogressRequestWritingSuffix
|
fsInprogressRequestWritingSuffix = fsInprogressRequestWritingSuffix
|
||||||
@@ -85,7 +85,7 @@ data class FileSystemTomlDto(
|
|||||||
inprogressRequestWritingSuffix = fsInprogressRequestWritingSuffix!!,
|
inprogressRequestWritingSuffix = fsInprogressRequestWritingSuffix!!,
|
||||||
inprogressProvingSuffixPattern = fsInprogressProvingSuffixPattern!!,
|
inprogressProvingSuffixPattern = fsInprogressProvingSuffixPattern!!,
|
||||||
pollingInterval = fsPollingInterval!!.toKotlinDuration(),
|
pollingInterval = fsPollingInterval!!.toKotlinDuration(),
|
||||||
pollingTimeout = fsPollingTimeout!!.toKotlinDuration()
|
pollingTimeout = fsPollingTimeout!!.toKotlinDuration(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,18 +25,18 @@ class BlockCreationMonitor(
|
|||||||
private val blockCreationListener: BlockCreationListener,
|
private val blockCreationListener: BlockCreationListener,
|
||||||
private val lastProvenBlockNumberProviderAsync: LastProvenBlockNumberProviderAsync,
|
private val lastProvenBlockNumberProviderAsync: LastProvenBlockNumberProviderAsync,
|
||||||
private val config: Config,
|
private val config: Config,
|
||||||
private val log: Logger = LogManager.getLogger(BlockCreationMonitor::class.java)
|
private val log: Logger = LogManager.getLogger(BlockCreationMonitor::class.java),
|
||||||
) : PeriodicPollingService(
|
) : PeriodicPollingService(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
pollingIntervalMs = config.pollingInterval.inWholeMilliseconds,
|
pollingIntervalMs = config.pollingInterval.inWholeMilliseconds,
|
||||||
log = log
|
log = log,
|
||||||
) {
|
) {
|
||||||
data class Config(
|
data class Config(
|
||||||
val pollingInterval: Duration,
|
val pollingInterval: Duration,
|
||||||
val blocksToFinalization: Long,
|
val blocksToFinalization: Long,
|
||||||
val blocksFetchLimit: Long,
|
val blocksFetchLimit: Long,
|
||||||
val startingBlockWaitTimeout: Duration = 14.days,
|
val startingBlockWaitTimeout: Duration = 14.days,
|
||||||
val lastL2BlockNumberToProcessInclusive: ULong? = null
|
val lastL2BlockNumberToProcessInclusive: ULong? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val _nexBlockNumberToFetch: AtomicLong = AtomicLong(startingBlockNumberExclusive + 1)
|
private val _nexBlockNumberToFetch: AtomicLong = AtomicLong(startingBlockNumberExclusive + 1)
|
||||||
@@ -76,7 +76,7 @@ class BlockCreationMonitor(
|
|||||||
log.warn(
|
log.warn(
|
||||||
"Block {} not found yet. Retrying in {}",
|
"Block {} not found yet. Retrying in {}",
|
||||||
startingBlockNumberExclusive,
|
startingBlockNumberExclusive,
|
||||||
config.pollingInterval
|
config.pollingInterval,
|
||||||
)
|
)
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
@@ -84,7 +84,7 @@ class BlockCreationMonitor(
|
|||||||
expectedParentBlockHash.set(block.hash)
|
expectedParentBlockHash.set(block.hash)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
) {
|
) {
|
||||||
web3j.ethGetBlock(startingBlockNumberExclusive.toBlockParameter())
|
web3j.ethGetBlock(startingBlockNumberExclusive.toBlockParameter())
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@ class BlockCreationMonitor(
|
|||||||
lastProvenBlockNumber,
|
lastProvenBlockNumber,
|
||||||
_nexBlockNumberToFetch.get(),
|
_nexBlockNumberToFetch.get(),
|
||||||
_nexBlockNumberToFetch.get() - lastProvenBlockNumber,
|
_nexBlockNumberToFetch.get() - lastProvenBlockNumber,
|
||||||
config.blocksFetchLimit
|
config.blocksFetchLimit,
|
||||||
)
|
)
|
||||||
SafeFuture.COMPLETE
|
SafeFuture.COMPLETE
|
||||||
} else if (config.lastL2BlockNumberToProcessInclusive != null &&
|
} else if (config.lastL2BlockNumberToProcessInclusive != null &&
|
||||||
@@ -115,7 +115,7 @@ class BlockCreationMonitor(
|
|||||||
"All blocks upto and including lastL2BlockNumberInclusiveToProcess={} have been processed. " +
|
"All blocks upto and including lastL2BlockNumberInclusiveToProcess={} have been processed. " +
|
||||||
"nextBlockNumberToFetch={}",
|
"nextBlockNumberToFetch={}",
|
||||||
config.lastL2BlockNumberToProcessInclusive,
|
config.lastL2BlockNumberToProcessInclusive,
|
||||||
nexBlockNumberToFetch
|
nexBlockNumberToFetch,
|
||||||
)
|
)
|
||||||
SafeFuture.COMPLETE
|
SafeFuture.COMPLETE
|
||||||
} else {
|
} else {
|
||||||
@@ -128,7 +128,7 @@ class BlockCreationMonitor(
|
|||||||
log.debug(
|
log.debug(
|
||||||
"updating nexBlockNumberToFetch from {} --> {}",
|
"updating nexBlockNumberToFetch from {} --> {}",
|
||||||
_nexBlockNumberToFetch.get(),
|
_nexBlockNumberToFetch.get(),
|
||||||
_nexBlockNumberToFetch.incrementAndGet()
|
_nexBlockNumberToFetch.incrementAndGet(),
|
||||||
)
|
)
|
||||||
expectedParentBlockHash.set(block.hash)
|
expectedParentBlockHash.set(block.hash)
|
||||||
}
|
}
|
||||||
@@ -140,7 +140,7 @@ class BlockCreationMonitor(
|
|||||||
block.number,
|
block.number,
|
||||||
block.hash.encodeHex(),
|
block.hash.encodeHex(),
|
||||||
block.parentHash.encodeHex(),
|
block.parentHash.encodeHex(),
|
||||||
expectedParentBlockHash.get().encodeHex()
|
expectedParentBlockHash.get().encodeHex(),
|
||||||
)
|
)
|
||||||
SafeFuture.failedFuture(IllegalStateException("Reorg detected on block ${block.number}"))
|
SafeFuture.failedFuture(IllegalStateException("Reorg detected on block ${block.number}"))
|
||||||
}
|
}
|
||||||
@@ -164,7 +164,7 @@ class BlockCreationMonitor(
|
|||||||
.thenApply {
|
.thenApply {
|
||||||
log.debug(
|
log.debug(
|
||||||
"blockCreationListener blockNumber={} resolved with success",
|
"blockCreationListener blockNumber={} resolved with success",
|
||||||
payload.number
|
payload.number,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.whenException { throwable ->
|
.whenException { throwable ->
|
||||||
@@ -172,7 +172,7 @@ class BlockCreationMonitor(
|
|||||||
"Failed to notify blockCreationListener: blockNumber={} errorMessage={}",
|
"Failed to notify blockCreationListener: blockNumber={} errorMessage={}",
|
||||||
payload.number,
|
payload.number,
|
||||||
throwable.message,
|
throwable.message,
|
||||||
throwable
|
throwable,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,7 +195,7 @@ class BlockCreationMonitor(
|
|||||||
"eth_getBlockByNumber({}) failed: errorMessage={}",
|
"eth_getBlockByNumber({}) failed: errorMessage={}",
|
||||||
blockNumber,
|
blockNumber,
|
||||||
it.message,
|
it.message,
|
||||||
it
|
it,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ import tech.pegasys.teku.infrastructure.async.SafeFuture
|
|||||||
|
|
||||||
class GethCliqueSafeBlockProvider(
|
class GethCliqueSafeBlockProvider(
|
||||||
private val web3j: Web3j,
|
private val web3j: Web3j,
|
||||||
private val config: Config
|
private val config: Config,
|
||||||
) : SafeBlockProvider {
|
) : SafeBlockProvider {
|
||||||
data class Config(
|
data class Config(
|
||||||
val blocksToFinalization: Long
|
val blocksToFinalization: Long,
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun getLatestSafeBlock(): SafeFuture<Block> {
|
override fun getLatestSafeBlock(): SafeFuture<Block> {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ interface LastProvenBlockNumberProviderSync {
|
|||||||
|
|
||||||
class BatchesRepoBasedLastProvenBlockNumberProvider(
|
class BatchesRepoBasedLastProvenBlockNumberProvider(
|
||||||
startingBlockNumberExclusive: Long,
|
startingBlockNumberExclusive: Long,
|
||||||
private val batchesRepository: BatchesRepository
|
private val batchesRepository: BatchesRepository,
|
||||||
) : LastProvenBlockNumberProviderAsync, LastProvenBlockNumberProviderSync {
|
) : LastProvenBlockNumberProviderAsync, LastProvenBlockNumberProviderSync {
|
||||||
private var latestL1FinalizedBlock: AtomicLong = AtomicLong(startingBlockNumberExclusive)
|
private var latestL1FinalizedBlock: AtomicLong = AtomicLong(startingBlockNumberExclusive)
|
||||||
private var lastProvenBlock: AtomicLong = AtomicLong(startingBlockNumberExclusive)
|
private var lastProvenBlock: AtomicLong = AtomicLong(startingBlockNumberExclusive)
|
||||||
@@ -35,7 +35,7 @@ class BatchesRepoBasedLastProvenBlockNumberProvider(
|
|||||||
|
|
||||||
private fun findAndCacheLastProvenBlockNumberFromDb(): SafeFuture<Long> {
|
private fun findAndCacheLastProvenBlockNumberFromDb(): SafeFuture<Long> {
|
||||||
return batchesRepository.findHighestConsecutiveEndBlockNumberFromBlockNumber(
|
return batchesRepository.findHighestConsecutiveEndBlockNumberFromBlockNumber(
|
||||||
latestL1FinalizedBlock.get() + 1
|
latestL1FinalizedBlock.get() + 1,
|
||||||
).thenApply {
|
).thenApply {
|
||||||
newValue ->
|
newValue ->
|
||||||
if (newValue != null) {
|
if (newValue != null) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package net.consensys.zkevm.ethereum.coordination
|
|||||||
import tech.pegasys.teku.infrastructure.async.SafeFuture
|
import tech.pegasys.teku.infrastructure.async.SafeFuture
|
||||||
|
|
||||||
class SimpleCompositeSafeFutureHandler<T>(
|
class SimpleCompositeSafeFutureHandler<T>(
|
||||||
private val handlers: List<(T) -> SafeFuture<*>>
|
private val handlers: List<(T) -> SafeFuture<*>>,
|
||||||
) : (T) -> SafeFuture<*> {
|
) : (T) -> SafeFuture<*> {
|
||||||
override fun invoke(arg: T): SafeFuture<Unit> {
|
override fun invoke(arg: T): SafeFuture<Unit> {
|
||||||
val handlingFutures =
|
val handlingFutures =
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import java.util.function.Supplier
|
|||||||
|
|
||||||
class ConsecutiveProvenBlobsProviderWithLastEndBlockNumberTracker(
|
class ConsecutiveProvenBlobsProviderWithLastEndBlockNumberTracker(
|
||||||
private val repository: AggregationsRepository,
|
private val repository: AggregationsRepository,
|
||||||
initialBlockNumber: ULong
|
initialBlockNumber: ULong,
|
||||||
) : ConsecutiveProvenBlobsProvider, Supplier<Number> {
|
) : ConsecutiveProvenBlobsProvider, Supplier<Number> {
|
||||||
private val cache = AtomicReference(initialBlockNumber)
|
private val cache = AtomicReference(initialBlockNumber)
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import linea.domain.BlockInterval
|
|||||||
import tech.pegasys.teku.infrastructure.async.SafeFuture
|
import tech.pegasys.teku.infrastructure.async.SafeFuture
|
||||||
|
|
||||||
class BlobZkStateProviderImpl(
|
class BlobZkStateProviderImpl(
|
||||||
private val zkStateClient: StateManagerClientV1
|
private val zkStateClient: StateManagerClientV1,
|
||||||
) : BlobZkStateProvider {
|
) : BlobZkStateProvider {
|
||||||
override fun getBlobZKState(blockRange: ULongRange): SafeFuture<BlobZkState> {
|
override fun getBlobZKState(blockRange: ULongRange): SafeFuture<BlobZkState> {
|
||||||
return zkStateClient
|
return zkStateClient
|
||||||
@@ -14,7 +14,7 @@ class BlobZkStateProviderImpl(
|
|||||||
.thenApply {
|
.thenApply {
|
||||||
BlobZkState(
|
BlobZkState(
|
||||||
parentStateRootHash = it.zkParentStateRootHash,
|
parentStateRootHash = it.zkParentStateRootHash,
|
||||||
finalStateRootHash = it.zkEndStateRootHash
|
finalStateRootHash = it.zkEndStateRootHash,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class ForkChoiceUpdaterImpl(private val rollupForkChoiceUpdatedClients: List<Rol
|
|||||||
log.debug(
|
log.debug(
|
||||||
"Updating finalized block: {}, to {} clients",
|
"Updating finalized block: {}, to {} clients",
|
||||||
finalizedBlockNumberAndHash,
|
finalizedBlockNumberAndHash,
|
||||||
rollupForkChoiceUpdatedClients.size
|
rollupForkChoiceUpdatedClients.size,
|
||||||
)
|
)
|
||||||
val futures: List<SafeFuture<*>> = rollupForkChoiceUpdatedClients.map { rollupForkChoiceUpdatedClient ->
|
val futures: List<SafeFuture<*>> = rollupForkChoiceUpdatedClients.map { rollupForkChoiceUpdatedClient ->
|
||||||
rollupForkChoiceUpdatedClient
|
rollupForkChoiceUpdatedClient
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class L1BasedLastFinalizedBlockProviderTest {
|
|||||||
whenever(lineaRollupClient.finalizedL2BlockNumber(eq(BlockParameter.Tag.LATEST)))
|
whenever(lineaRollupClient.finalizedL2BlockNumber(eq(BlockParameter.Tag.LATEST)))
|
||||||
.thenReturn(
|
.thenReturn(
|
||||||
SafeFuture.completedFuture(replies[0]),
|
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(
|
val resumerCalculator = L1BasedLastFinalizedBlockProvider(
|
||||||
@@ -36,7 +36,7 @@ class L1BasedLastFinalizedBlockProviderTest {
|
|||||||
lineaRollupClient,
|
lineaRollupClient,
|
||||||
consistentNumberOfBlocksOnL1 = 3u,
|
consistentNumberOfBlocksOnL1 = 3u,
|
||||||
numberOfRetries = 50u,
|
numberOfRetries = 50u,
|
||||||
pollingInterval = 10.milliseconds
|
pollingInterval = 10.milliseconds,
|
||||||
)
|
)
|
||||||
|
|
||||||
assertThat(resumerCalculator.getLastFinalizedBlock().get()).isEqualTo(101.toULong())
|
assertThat(resumerCalculator.getLastFinalizedBlock().get()).isEqualTo(101.toULong())
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class L1DependentAppTest {
|
|||||||
val lastProcessedBlock =
|
val lastProcessedBlock =
|
||||||
L1DependentApp.resumeConflationFrom(
|
L1DependentApp.resumeConflationFrom(
|
||||||
aggregationsRepository,
|
aggregationsRepository,
|
||||||
lastFinalizedBlock
|
lastFinalizedBlock,
|
||||||
).get()
|
).get()
|
||||||
assertThat(lastProcessedBlock).isEqualTo(lastFinalizedBlock)
|
assertThat(lastProcessedBlock).isEqualTo(lastFinalizedBlock)
|
||||||
verify(aggregationsRepository).findConsecutiveProvenBlobs(lastFinalizedBlock.toLong() + 1)
|
verify(aggregationsRepository).findConsecutiveProvenBlobs(lastFinalizedBlock.toLong() + 1)
|
||||||
@@ -49,12 +49,12 @@ class L1DependentAppTest {
|
|||||||
lastConsecutiveAggregatedBlockNumber = lastConsecutiveAggregatedBlockNumber,
|
lastConsecutiveAggregatedBlockNumber = lastConsecutiveAggregatedBlockNumber,
|
||||||
batchesRepository = batchesRepository,
|
batchesRepository = batchesRepository,
|
||||||
blobsRepository = blobsRepository,
|
blobsRepository = blobsRepository,
|
||||||
aggregationsRepository = aggregationsRepository
|
aggregationsRepository = aggregationsRepository,
|
||||||
).get()
|
).get()
|
||||||
verify(batchesRepository).deleteBatchesAfterBlockNumber((lastProcessedBlock + 1uL).toLong())
|
verify(batchesRepository).deleteBatchesAfterBlockNumber((lastProcessedBlock + 1uL).toLong())
|
||||||
verify(blobsRepository).deleteBlobsAfterBlockNumber(lastProcessedBlock + 1uL)
|
verify(blobsRepository).deleteBlobsAfterBlockNumber(lastProcessedBlock + 1uL)
|
||||||
verify(aggregationsRepository).deleteAggregationsAfterBlockNumber(
|
verify(aggregationsRepository).deleteAggregationsAfterBlockNumber(
|
||||||
(lastConsecutiveAggregatedBlockNumber + 1uL).toLong()
|
(lastConsecutiveAggregatedBlockNumber + 1uL).toLong(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ class CoordinatorConfigTest {
|
|||||||
_smartContractErrors = mapOf(
|
_smartContractErrors = mapOf(
|
||||||
// L1 Linea Rollup
|
// L1 Linea Rollup
|
||||||
"0f06cd15" to "DataAlreadySubmitted",
|
"0f06cd15" to "DataAlreadySubmitted",
|
||||||
"c01eab56" to "EmptySubmissionData"
|
"c01eab56" to "EmptySubmissionData",
|
||||||
),
|
),
|
||||||
fetchBlocksLimit = 4000
|
fetchBlocksLimit = 4000,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val proversConfig = ProversConfig(
|
private val proversConfig = ProversConfig(
|
||||||
@@ -58,7 +58,7 @@ class CoordinatorConfigTest {
|
|||||||
pollingInterval = 1.seconds,
|
pollingInterval = 1.seconds,
|
||||||
pollingTimeout = 10.minutes,
|
pollingTimeout = 10.minutes,
|
||||||
inprogressProvingSuffixPattern = ".*\\.inprogress\\.prover.*",
|
inprogressProvingSuffixPattern = ".*\\.inprogress\\.prover.*",
|
||||||
inprogressRequestWritingSuffix = ".inprogress_coordinator_writing"
|
inprogressRequestWritingSuffix = ".inprogress_coordinator_writing",
|
||||||
),
|
),
|
||||||
blobCompression = FileBasedProverConfig(
|
blobCompression = FileBasedProverConfig(
|
||||||
requestsDirectory = Path.of("/data/prover/v2/compression/requests"),
|
requestsDirectory = Path.of("/data/prover/v2/compression/requests"),
|
||||||
@@ -66,7 +66,7 @@ class CoordinatorConfigTest {
|
|||||||
pollingInterval = 1.seconds,
|
pollingInterval = 1.seconds,
|
||||||
pollingTimeout = 10.minutes,
|
pollingTimeout = 10.minutes,
|
||||||
inprogressProvingSuffixPattern = ".*\\.inprogress\\.prover.*",
|
inprogressProvingSuffixPattern = ".*\\.inprogress\\.prover.*",
|
||||||
inprogressRequestWritingSuffix = ".inprogress_coordinator_writing"
|
inprogressRequestWritingSuffix = ".inprogress_coordinator_writing",
|
||||||
),
|
),
|
||||||
proofAggregation = FileBasedProverConfig(
|
proofAggregation = FileBasedProverConfig(
|
||||||
requestsDirectory = Path.of("/data/prover/v2/aggregation/requests"),
|
requestsDirectory = Path.of("/data/prover/v2/aggregation/requests"),
|
||||||
@@ -74,24 +74,24 @@ class CoordinatorConfigTest {
|
|||||||
pollingInterval = 1.seconds,
|
pollingInterval = 1.seconds,
|
||||||
pollingTimeout = 10.minutes,
|
pollingTimeout = 10.minutes,
|
||||||
inprogressProvingSuffixPattern = ".*\\.inprogress\\.prover.*",
|
inprogressProvingSuffixPattern = ".*\\.inprogress\\.prover.*",
|
||||||
inprogressRequestWritingSuffix = ".inprogress_coordinator_writing"
|
inprogressRequestWritingSuffix = ".inprogress_coordinator_writing",
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
switchBlockNumberInclusive = null,
|
switchBlockNumberInclusive = null,
|
||||||
proverB = null
|
proverB = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val blobCompressionConfig = BlobCompressionConfig(
|
private val blobCompressionConfig = BlobCompressionConfig(
|
||||||
blobSizeLimit = 100 * 1024,
|
blobSizeLimit = 100 * 1024,
|
||||||
handlerPollingInterval = Duration.parse("PT1S"),
|
handlerPollingInterval = Duration.parse("PT1S"),
|
||||||
_batchesLimit = 1
|
_batchesLimit = 1,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val aggregationConfig = AggregationConfig(
|
private val aggregationConfig = AggregationConfig(
|
||||||
aggregationProofsLimit = 3,
|
aggregationProofsLimit = 3,
|
||||||
aggregationDeadline = Duration.parse("PT10S"),
|
aggregationDeadline = Duration.parse("PT10S"),
|
||||||
aggregationCoordinatorPollingInterval = Duration.parse("PT2S"),
|
aggregationCoordinatorPollingInterval = Duration.parse("PT2S"),
|
||||||
deadlineCheckInterval = Duration.parse("PT8S")
|
deadlineCheckInterval = Duration.parse("PT8S"),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val tracesConfig = TracesConfig(
|
private val tracesConfig = TracesConfig(
|
||||||
@@ -103,38 +103,38 @@ class CoordinatorConfigTest {
|
|||||||
requestLimitPerEndpoint = 1U,
|
requestLimitPerEndpoint = 1U,
|
||||||
requestRetry = RequestRetryConfigTomlFriendly(
|
requestRetry = RequestRetryConfigTomlFriendly(
|
||||||
backoffDelay = Duration.parse("PT1S"),
|
backoffDelay = Duration.parse("PT1S"),
|
||||||
failuresWarningThreshold = 2
|
failuresWarningThreshold = 2,
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
countersV2 = TracesConfig.FunctionalityEndpoint(
|
countersV2 = TracesConfig.FunctionalityEndpoint(
|
||||||
endpoints = listOf(URI("http://traces-node:8545/").toURL()),
|
endpoints = listOf(URI("http://traces-node:8545/").toURL()),
|
||||||
requestLimitPerEndpoint = 1U,
|
requestLimitPerEndpoint = 1U,
|
||||||
requestRetry = RequestRetryConfigTomlFriendly(
|
requestRetry = RequestRetryConfigTomlFriendly(
|
||||||
backoffDelay = Duration.parse("PT1S"),
|
backoffDelay = Duration.parse("PT1S"),
|
||||||
failuresWarningThreshold = 2
|
failuresWarningThreshold = 2,
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val type2StateProofProviderConfig = Type2StateProofProviderConfig(
|
private val type2StateProofProviderConfig = Type2StateProofProviderConfig(
|
||||||
endpoints = listOf(URI("http://shomei-frontend:8888/").toURL()),
|
endpoints = listOf(URI("http://shomei-frontend:8888/").toURL()),
|
||||||
requestRetry = RequestRetryConfigTomlFriendly(
|
requestRetry = RequestRetryConfigTomlFriendly(
|
||||||
backoffDelay = Duration.parse("PT1S"),
|
backoffDelay = Duration.parse("PT1S"),
|
||||||
failuresWarningThreshold = 2
|
failuresWarningThreshold = 2,
|
||||||
),
|
),
|
||||||
l1QueryBlockTag = BlockParameter.Tag.SAFE,
|
l1QueryBlockTag = BlockParameter.Tag.SAFE,
|
||||||
l1PollingInterval = Duration.parse("PT6S")
|
l1PollingInterval = Duration.parse("PT6S"),
|
||||||
)
|
)
|
||||||
private val stateManagerConfig = StateManagerClientConfig(
|
private val stateManagerConfig = StateManagerClientConfig(
|
||||||
version = "2.3.0",
|
version = "2.3.0",
|
||||||
endpoints = listOf(
|
endpoints = listOf(
|
||||||
URI("http://shomei:8888/").toURL()
|
URI("http://shomei:8888/").toURL(),
|
||||||
),
|
),
|
||||||
requestLimitPerEndpoint = 2U,
|
requestLimitPerEndpoint = 2U,
|
||||||
requestRetry = RequestRetryConfigTomlFriendly(
|
requestRetry = RequestRetryConfigTomlFriendly(
|
||||||
backoffDelay = Duration.parse("PT2S"),
|
backoffDelay = Duration.parse("PT2S"),
|
||||||
failuresWarningThreshold = 2
|
failuresWarningThreshold = 2,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val blobSubmissionConfig = BlobSubmissionConfig(
|
private val blobSubmissionConfig = BlobSubmissionConfig(
|
||||||
@@ -146,7 +146,7 @@ class CoordinatorConfigTest {
|
|||||||
proofSubmissionDelay = Duration.parse("PT1S"),
|
proofSubmissionDelay = Duration.parse("PT1S"),
|
||||||
targetBlobsToSendPerTransaction = 9,
|
targetBlobsToSendPerTransaction = 9,
|
||||||
useEthEstimateGas = false,
|
useEthEstimateGas = false,
|
||||||
disabled = false
|
disabled = false,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val aggregationFinalizationConfig = AggregationFinalizationConfig(
|
private val aggregationFinalizationConfig = AggregationFinalizationConfig(
|
||||||
@@ -154,7 +154,7 @@ class CoordinatorConfigTest {
|
|||||||
maxAggregationsToFinalizePerTick = 1,
|
maxAggregationsToFinalizePerTick = 1,
|
||||||
proofSubmissionDelay = Duration.parse("PT1S"),
|
proofSubmissionDelay = Duration.parse("PT1S"),
|
||||||
useEthEstimateGas = true,
|
useEthEstimateGas = true,
|
||||||
disabled = false
|
disabled = false,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val databaseConfig = DatabaseConfig(
|
private val databaseConfig = DatabaseConfig(
|
||||||
@@ -165,12 +165,12 @@ class CoordinatorConfigTest {
|
|||||||
schema = "linea_coordinator",
|
schema = "linea_coordinator",
|
||||||
readPoolSize = 10,
|
readPoolSize = 10,
|
||||||
readPipeliningLimit = 10,
|
readPipeliningLimit = 10,
|
||||||
transactionalPoolSize = 10
|
transactionalPoolSize = 10,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val persistenceRetryConfig = PersistenceRetryConfig(
|
private val persistenceRetryConfig = PersistenceRetryConfig(
|
||||||
maxRetries = null,
|
maxRetries = null,
|
||||||
backoffDelay = Duration.parse("PT1S")
|
backoffDelay = Duration.parse("PT1S"),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val l1Config = L1Config(
|
private val l1Config = L1Config(
|
||||||
@@ -194,7 +194,7 @@ class CoordinatorConfigTest {
|
|||||||
blockRangeLoopLimit = 500U,
|
blockRangeLoopLimit = 500U,
|
||||||
_ethFeeHistoryEndpoint = null,
|
_ethFeeHistoryEndpoint = null,
|
||||||
_genesisStateRootHash = "0x072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd",
|
_genesisStateRootHash = "0x072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd",
|
||||||
_genesisShnarfV6 = "0x47452a1b9ebadfe02bdd02f580fa1eba17680d57eec968a591644d05d78ee84f"
|
_genesisShnarfV6 = "0x47452a1b9ebadfe02bdd02f580fa1eba17680d57eec968a591644d05d78ee84f",
|
||||||
)
|
)
|
||||||
|
|
||||||
private val l2Config = L2Config(
|
private val l2Config = L2Config(
|
||||||
@@ -208,7 +208,7 @@ class CoordinatorConfigTest {
|
|||||||
lastHashSearchWindow = 25U,
|
lastHashSearchWindow = 25U,
|
||||||
anchoringReceiptPollingInterval = Duration.parse("PT01S"),
|
anchoringReceiptPollingInterval = Duration.parse("PT01S"),
|
||||||
maxReceiptRetries = 120U,
|
maxReceiptRetries = 120U,
|
||||||
newBlockPollingInterval = Duration.parse("PT1S")
|
newBlockPollingInterval = Duration.parse("PT1S"),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val finalizationSigner = SignerConfig(
|
private val finalizationSigner = SignerConfig(
|
||||||
@@ -219,9 +219,9 @@ class CoordinatorConfigTest {
|
|||||||
keepAlive = true,
|
keepAlive = true,
|
||||||
publicKey =
|
publicKey =
|
||||||
"ba5734d8f7091719471e7f7ed6b9df170dc70cc661ca05e688601ad984f068b0d67351e5f06073092499336ab0839ef8a521afd334e5" +
|
"ba5734d8f7091719471e7f7ed6b9df170dc70cc661ca05e688601ad984f068b0d67351e5f06073092499336ab0839ef8a521afd334e5" +
|
||||||
"3807205fa2f08eec74f4"
|
"3807205fa2f08eec74f4",
|
||||||
),
|
),
|
||||||
web3j = Web3jConfig(Masked("0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"))
|
web3j = Web3jConfig(Masked("0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d")),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val dataSubmissionSigner = SignerConfig(
|
private val dataSubmissionSigner = SignerConfig(
|
||||||
@@ -232,9 +232,9 @@ class CoordinatorConfigTest {
|
|||||||
keepAlive = true,
|
keepAlive = true,
|
||||||
publicKey =
|
publicKey =
|
||||||
"9d9031e97dd78ff8c15aa86939de9b1e791066a0224e331bc962a2099a7b1f0464b8bbafe1535f2301c72c2cb3535b172da30b02686a" +
|
"9d9031e97dd78ff8c15aa86939de9b1e791066a0224e331bc962a2099a7b1f0464b8bbafe1535f2301c72c2cb3535b172da30b02686a" +
|
||||||
"b0393d348614f157fbdb"
|
"b0393d348614f157fbdb",
|
||||||
),
|
),
|
||||||
web3j = Web3jConfig(Masked("0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a"))
|
web3j = Web3jConfig(Masked("0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a")),
|
||||||
)
|
)
|
||||||
private val l2SignerConfig = SignerConfig(
|
private val l2SignerConfig = SignerConfig(
|
||||||
type = SignerConfig.Type.Web3j,
|
type = SignerConfig.Type.Web3j,
|
||||||
@@ -244,43 +244,43 @@ class CoordinatorConfigTest {
|
|||||||
keepAlive = true,
|
keepAlive = true,
|
||||||
publicKey =
|
publicKey =
|
||||||
"4a788ad6fa008beed58de6418369717d7492f37d173d70e2c26d9737e2c6eeae929452ef8602a19410844db3e200a0e73f5208fd7625" +
|
"4a788ad6fa008beed58de6418369717d7492f37d173d70e2c26d9737e2c6eeae929452ef8602a19410844db3e200a0e73f5208fd7625" +
|
||||||
"9a8766b73953fc3e7023"
|
"9a8766b73953fc3e7023",
|
||||||
),
|
),
|
||||||
web3j = Web3jConfig(Masked("0x4d01ae6487860981699236a58b68f807ee5f17b12df5740b85cf4c4653be0f55"))
|
web3j = Web3jConfig(Masked("0x4d01ae6487860981699236a58b68f807ee5f17b12df5740b85cf4c4653be0f55")),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val l2NetworkGasPricingRequestRetryConfig = RequestRetryConfig(
|
private val l2NetworkGasPricingRequestRetryConfig = RequestRetryConfig(
|
||||||
maxRetries = 3u,
|
maxRetries = 3u,
|
||||||
timeout = 6.seconds,
|
timeout = 6.seconds,
|
||||||
backoffDelay = 1.seconds,
|
backoffDelay = 1.seconds,
|
||||||
failuresWarningThreshold = 2u
|
failuresWarningThreshold = 2u,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val l2NetworkGasPricingServiceConfig = L2NetworkGasPricingService.Config(
|
private val l2NetworkGasPricingServiceConfig = L2NetworkGasPricingService.Config(
|
||||||
feeHistoryFetcherConfig = FeeHistoryFetcherImpl.Config(
|
feeHistoryFetcherConfig = FeeHistoryFetcherImpl.Config(
|
||||||
feeHistoryBlockCount = 50U,
|
feeHistoryBlockCount = 50U,
|
||||||
feeHistoryRewardPercentile = 15.0
|
feeHistoryRewardPercentile = 15.0,
|
||||||
),
|
),
|
||||||
legacy = L2NetworkGasPricingService.LegacyGasPricingCalculatorConfig(
|
legacy = L2NetworkGasPricingService.LegacyGasPricingCalculatorConfig(
|
||||||
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
|
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
|
||||||
feeUpperBound = 10_000_000_000.0,
|
feeUpperBound = 10_000_000_000.0,
|
||||||
feeLowerBound = 90_000_000.0,
|
feeLowerBound = 90_000_000.0,
|
||||||
feeMargin = 0.0
|
feeMargin = 0.0,
|
||||||
),
|
),
|
||||||
transactionCostCalculatorConfig = TransactionCostCalculator.Config(
|
transactionCostCalculatorConfig = TransactionCostCalculator.Config(
|
||||||
sampleTransactionCostMultiplier = 1.0,
|
sampleTransactionCostMultiplier = 1.0,
|
||||||
fixedCostWei = 3000000u,
|
fixedCostWei = 3000000u,
|
||||||
compressedTxSize = 125,
|
compressedTxSize = 125,
|
||||||
expectedGas = 21000
|
expectedGas = 21000,
|
||||||
),
|
),
|
||||||
naiveGasPricingCalculatorConfig = null
|
naiveGasPricingCalculatorConfig = null,
|
||||||
),
|
),
|
||||||
jsonRpcGasPriceUpdaterConfig = GasPriceUpdaterImpl.Config(
|
jsonRpcGasPriceUpdaterConfig = GasPriceUpdaterImpl.Config(
|
||||||
gethEndpoints = listOf(
|
gethEndpoints = listOf(
|
||||||
URI("http://l2-node:8545/").toURL()
|
URI("http://l2-node:8545/").toURL(),
|
||||||
),
|
),
|
||||||
besuEndPoints = listOf(),
|
besuEndPoints = listOf(),
|
||||||
retryConfig = l2NetworkGasPricingRequestRetryConfig
|
retryConfig = l2NetworkGasPricingRequestRetryConfig,
|
||||||
),
|
),
|
||||||
jsonRpcPriceUpdateInterval = 12.seconds,
|
jsonRpcPriceUpdateInterval = 12.seconds,
|
||||||
extraDataPricingPropagationEnabled = true,
|
extraDataPricingPropagationEnabled = true,
|
||||||
@@ -289,21 +289,21 @@ class CoordinatorConfigTest {
|
|||||||
blobSubmissionExpectedExecutionGas = 213_000u,
|
blobSubmissionExpectedExecutionGas = 213_000u,
|
||||||
bytesPerDataSubmission = 131072u,
|
bytesPerDataSubmission = 131072u,
|
||||||
expectedBlobGas = 131072u,
|
expectedBlobGas = 131072u,
|
||||||
margin = 4.0
|
margin = 4.0,
|
||||||
),
|
),
|
||||||
variableFeesCalculatorBounds = BoundableFeeCalculator.Config(
|
variableFeesCalculatorBounds = BoundableFeeCalculator.Config(
|
||||||
feeUpperBound = 10_000_000_001.0,
|
feeUpperBound = 10_000_000_001.0,
|
||||||
feeLowerBound = 90_000_001.0,
|
feeLowerBound = 90_000_001.0,
|
||||||
feeMargin = 0.0
|
feeMargin = 0.0,
|
||||||
),
|
),
|
||||||
extraDataCalculatorConfig = MinerExtraDataV1CalculatorImpl.Config(
|
extraDataCalculatorConfig = MinerExtraDataV1CalculatorImpl.Config(
|
||||||
fixedCostInKWei = 3000u,
|
fixedCostInKWei = 3000u,
|
||||||
ethGasPriceMultiplier = 1.2
|
ethGasPriceMultiplier = 1.2,
|
||||||
),
|
),
|
||||||
extraDataUpdaterConfig = ExtraDataV1UpdaterImpl.Config(
|
extraDataUpdaterConfig = ExtraDataV1UpdaterImpl.Config(
|
||||||
sequencerEndpoint = URI(/* str = */ "http://sequencer:8545/").toURL(),
|
sequencerEndpoint = URI("http://sequencer:8545/").toURL(),
|
||||||
retryConfig = l2NetworkGasPricingRequestRetryConfig
|
retryConfig = l2NetworkGasPricingRequestRetryConfig,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val l1DynamicGasPriceCapServiceConfig = L1DynamicGasPriceCapServiceConfig(
|
private val l1DynamicGasPriceCapServiceConfig = L1DynamicGasPriceCapServiceConfig(
|
||||||
@@ -318,18 +318,18 @@ class CoordinatorConfigTest {
|
|||||||
gasPriceCapsCheckCoefficient = 0.9,
|
gasPriceCapsCheckCoefficient = 0.9,
|
||||||
historicBaseFeePerBlobGasLowerBound = 100_000_000u,
|
historicBaseFeePerBlobGasLowerBound = 100_000_000u,
|
||||||
historicAvgRewardConstant = 100_000_000u,
|
historicAvgRewardConstant = 100_000_000u,
|
||||||
timeOfDayMultipliers = expectedTimeOfDayMultipliers
|
timeOfDayMultipliers = expectedTimeOfDayMultipliers,
|
||||||
),
|
),
|
||||||
feeHistoryFetcher = L1DynamicGasPriceCapServiceConfig.FeeHistoryFetcher(
|
feeHistoryFetcher = L1DynamicGasPriceCapServiceConfig.FeeHistoryFetcher(
|
||||||
fetchInterval = Duration.parse("PT1S"),
|
fetchInterval = Duration.parse("PT1S"),
|
||||||
maxBlockCount = 1000U,
|
maxBlockCount = 1000U,
|
||||||
rewardPercentiles = listOf(10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0),
|
rewardPercentiles = listOf(10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0),
|
||||||
numOfBlocksBeforeLatest = 4U,
|
numOfBlocksBeforeLatest = 4U,
|
||||||
endpoint = null
|
endpoint = null,
|
||||||
),
|
),
|
||||||
feeHistoryStorage = L1DynamicGasPriceCapServiceConfig.FeeHistoryStorage(
|
feeHistoryStorage = L1DynamicGasPriceCapServiceConfig.FeeHistoryStorage(
|
||||||
storagePeriod = Duration.parse("PT2M")
|
storagePeriod = Duration.parse("PT2M"),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val coordinatorConfig = CoordinatorConfig(
|
private val coordinatorConfig = CoordinatorConfig(
|
||||||
@@ -351,11 +351,11 @@ class CoordinatorConfigTest {
|
|||||||
l2Signer = l2SignerConfig,
|
l2Signer = l2SignerConfig,
|
||||||
messageAnchoring = MessageAnchoringConfigTomlDto().reified(
|
messageAnchoring = MessageAnchoringConfigTomlDto().reified(
|
||||||
l1DefaultEndpoint = l1Config.rpcEndpoint,
|
l1DefaultEndpoint = l1Config.rpcEndpoint,
|
||||||
l2DefaultEndpoint = l2Config.rpcEndpoint
|
l2DefaultEndpoint = l2Config.rpcEndpoint,
|
||||||
),
|
),
|
||||||
l2NetworkGasPricingService = l2NetworkGasPricingServiceConfig,
|
l2NetworkGasPricingService = l2NetworkGasPricingServiceConfig,
|
||||||
l1DynamicGasPriceCapService = l1DynamicGasPriceCapServiceConfig,
|
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-traces-v2-override.config.toml"),
|
||||||
Path.of("../../config/coordinator/coordinator-docker-web3signer-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.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"),
|
tracesLimitsFileV2 = Path.of("../../config/common/traces-limits-v2.toml"),
|
||||||
gasPriceCapTimeOfDayMultipliersFile = Path.of("../../config/common/gas-price-cap-time-of-day-multipliers.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 {
|
private fun pathToResource(resource: String): Path {
|
||||||
return Paths.get(
|
return Paths.get(
|
||||||
this::class.java.classLoader.getResource(resource)?.toURI()
|
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")),
|
coordinatorConfigFiles = listOf(pathToResource("configs/coordinator.config.toml")),
|
||||||
tracesLimitsFileV2 = pathToResource("configs/traces-limits-v2.toml"),
|
tracesLimitsFileV2 = pathToResource("configs/traces-limits-v2.toml"),
|
||||||
gasPriceCapTimeOfDayMultipliersFile = pathToResource("configs/gas-price-cap-time-of-day-multipliers.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)
|
assertEquals(coordinatorConfig, configs)
|
||||||
@@ -404,18 +404,18 @@ class CoordinatorConfigTest {
|
|||||||
val config = loadConfigs(
|
val config = loadConfigs(
|
||||||
coordinatorConfigFiles = listOf(
|
coordinatorConfigFiles = listOf(
|
||||||
pathToResource("configs/coordinator.config.toml"),
|
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"),
|
tracesLimitsFileV2 = pathToResource("configs/traces-limits-v2.toml"),
|
||||||
gasPriceCapTimeOfDayMultipliersFile = pathToResource("configs/gas-price-cap-time-of-day-multipliers.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 =
|
val expectedConfig =
|
||||||
coordinatorConfig.copy(
|
coordinatorConfig.copy(
|
||||||
finalizationSigner = finalizationSigner.copy(type = SignerConfig.Type.Web3Signer),
|
finalizationSigner = finalizationSigner.copy(type = SignerConfig.Type.Web3Signer),
|
||||||
dataSubmissionSigner = dataSubmissionSigner.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)
|
assertThat(config).isEqualTo(expectedConfig)
|
||||||
@@ -426,11 +426,11 @@ class CoordinatorConfigTest {
|
|||||||
val config = loadConfigs(
|
val config = loadConfigs(
|
||||||
coordinatorConfigFiles = listOf(
|
coordinatorConfigFiles = listOf(
|
||||||
pathToResource("configs/coordinator.config.toml"),
|
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"),
|
tracesLimitsFileV2 = pathToResource("configs/traces-limits-v2.toml"),
|
||||||
gasPriceCapTimeOfDayMultipliersFile = pathToResource("configs/gas-price-cap-time-of-day-multipliers.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 =
|
val expectedConfig =
|
||||||
@@ -441,31 +441,31 @@ class CoordinatorConfigTest {
|
|||||||
transactionCostCalculatorConfig =
|
transactionCostCalculatorConfig =
|
||||||
l2NetworkGasPricingServiceConfig.legacy.transactionCostCalculatorConfig?.copy(
|
l2NetworkGasPricingServiceConfig.legacy.transactionCostCalculatorConfig?.copy(
|
||||||
compressedTxSize = 350,
|
compressedTxSize = 350,
|
||||||
expectedGas = 29400
|
expectedGas = 29400,
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
traces = tracesConfig.copy(
|
traces = tracesConfig.copy(
|
||||||
blobCompressorVersion = BlobCompressorVersion.V1_2,
|
blobCompressorVersion = BlobCompressorVersion.V1_2,
|
||||||
expectedTracesApiVersionV2 = "v0.8.0-rc8",
|
expectedTracesApiVersionV2 = "v0.8.0-rc8",
|
||||||
conflationV2 = tracesConfig.conflationV2,
|
conflationV2 = tracesConfig.conflationV2,
|
||||||
countersV2 = tracesConfig.countersV2
|
countersV2 = tracesConfig.countersV2,
|
||||||
),
|
),
|
||||||
proversConfig = proversConfig.copy(
|
proversConfig = proversConfig.copy(
|
||||||
proverA = proversConfig.proverA.copy(
|
proverA = proversConfig.proverA.copy(
|
||||||
execution = proversConfig.proverA.execution.copy(
|
execution = proversConfig.proverA.execution.copy(
|
||||||
requestsDirectory = Path.of("/data/prover/v3/execution/requests"),
|
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(
|
blobCompression = proversConfig.proverA.blobCompression.copy(
|
||||||
requestsDirectory = Path.of("/data/prover/v3/compression/requests"),
|
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(
|
proofAggregation = proversConfig.proverA.proofAggregation.copy(
|
||||||
requestsDirectory = Path.of("/data/prover/v3/aggregation/requests"),
|
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(
|
messageAnchoring = MessageAnchoringConfigTomlDto().copy(
|
||||||
l1Endpoint = URI("http://l1-endpoint-for-anchoring:8545").toURL(),
|
l1Endpoint = URI("http://l1-endpoint-for-anchoring:8545").toURL(),
|
||||||
@@ -475,12 +475,12 @@ class CoordinatorConfigTest {
|
|||||||
anchoringTickInterval = 1.seconds.toJavaDuration(),
|
anchoringTickInterval = 1.seconds.toJavaDuration(),
|
||||||
l1RequestRetries = RequestRetryConfigTomlFriendly(
|
l1RequestRetries = RequestRetryConfigTomlFriendly(
|
||||||
maxRetries = 10,
|
maxRetries = 10,
|
||||||
failuresWarningThreshold = 1
|
failuresWarningThreshold = 1,
|
||||||
)
|
),
|
||||||
).reified(
|
).reified(
|
||||||
l1DefaultEndpoint = l1Config.rpcEndpoint,
|
l1DefaultEndpoint = l1Config.rpcEndpoint,
|
||||||
l2DefaultEndpoint = l2Config.rpcEndpoint
|
l2DefaultEndpoint = l2Config.rpcEndpoint,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
assertThat(config).isEqualTo(expectedConfig)
|
assertThat(config).isEqualTo(expectedConfig)
|
||||||
@@ -489,7 +489,7 @@ class CoordinatorConfigTest {
|
|||||||
@Test
|
@Test
|
||||||
fun invalidConfigReturnsErrorResult() {
|
fun invalidConfigReturnsErrorResult() {
|
||||||
val configsResult = loadConfigsOrError<TestConfig>(
|
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")
|
assertThat(configsResult.getError()).contains("'extraField': Missing String from config")
|
||||||
@@ -498,17 +498,17 @@ class CoordinatorConfigTest {
|
|||||||
@Test
|
@Test
|
||||||
fun testInvalidAggregationByTargetBlockNumberWhenL2InclusiveBlockNumberToStopAndFlushAggregationSpecified() {
|
fun testInvalidAggregationByTargetBlockNumberWhenL2InclusiveBlockNumberToStopAndFlushAggregationSpecified() {
|
||||||
val aggregationConfigWithoutTargetBlockNumber = aggregationConfig.copy(
|
val aggregationConfigWithoutTargetBlockNumber = aggregationConfig.copy(
|
||||||
_targetEndBlocks = emptyList()
|
_targetEndBlocks = emptyList(),
|
||||||
)
|
)
|
||||||
val conflationConfigWithTargetBlockNumber = conflationConfig.copy(
|
val conflationConfigWithTargetBlockNumber = conflationConfig.copy(
|
||||||
_conflationTargetEndBlockNumbers = listOf(100L)
|
_conflationTargetEndBlockNumbers = listOf(100L),
|
||||||
)
|
)
|
||||||
|
|
||||||
val exception = assertThrows<IllegalArgumentException> {
|
val exception = assertThrows<IllegalArgumentException> {
|
||||||
coordinatorConfig.copy(
|
coordinatorConfig.copy(
|
||||||
l2InclusiveBlockNumberToStopAndFlushAggregation = 100uL,
|
l2InclusiveBlockNumberToStopAndFlushAggregation = 100uL,
|
||||||
proofAggregation = aggregationConfigWithoutTargetBlockNumber,
|
proofAggregation = aggregationConfigWithoutTargetBlockNumber,
|
||||||
conflation = conflationConfigWithTargetBlockNumber
|
conflation = conflationConfigWithTargetBlockNumber,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
assertThat(exception.message)
|
assertThat(exception.message)
|
||||||
@@ -518,40 +518,40 @@ class CoordinatorConfigTest {
|
|||||||
@Test
|
@Test
|
||||||
fun testInvalidConflationByTargetBlockNumberWhenL2InclusiveBlockNumberToStopAndFlushAggregationSpecified() {
|
fun testInvalidConflationByTargetBlockNumberWhenL2InclusiveBlockNumberToStopAndFlushAggregationSpecified() {
|
||||||
val aggregationConfigWithTargetBlockNumber = aggregationConfig.copy(
|
val aggregationConfigWithTargetBlockNumber = aggregationConfig.copy(
|
||||||
_targetEndBlocks = listOf(100L)
|
_targetEndBlocks = listOf(100L),
|
||||||
)
|
)
|
||||||
val conflationConfigWithoutTargetBlockNumber = conflationConfig.copy(
|
val conflationConfigWithoutTargetBlockNumber = conflationConfig.copy(
|
||||||
_conflationTargetEndBlockNumbers = emptyList()
|
_conflationTargetEndBlockNumbers = emptyList(),
|
||||||
)
|
)
|
||||||
|
|
||||||
val exception = assertThrows<IllegalArgumentException> {
|
val exception = assertThrows<IllegalArgumentException> {
|
||||||
coordinatorConfig.copy(
|
coordinatorConfig.copy(
|
||||||
l2InclusiveBlockNumberToStopAndFlushAggregation = 100uL,
|
l2InclusiveBlockNumberToStopAndFlushAggregation = 100uL,
|
||||||
proofAggregation = aggregationConfigWithTargetBlockNumber,
|
proofAggregation = aggregationConfigWithTargetBlockNumber,
|
||||||
conflation = conflationConfigWithoutTargetBlockNumber
|
conflation = conflationConfigWithoutTargetBlockNumber,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
assertThat(exception.message)
|
assertThat(exception.message)
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
"conflation.conflationTargetEndBlockNumbers should contain the " +
|
"conflation.conflationTargetEndBlockNumbers should contain the " +
|
||||||
"l2InclusiveBlockNumberToStopAndFlushAggregation"
|
"l2InclusiveBlockNumberToStopAndFlushAggregation",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testValidAggrAndConflationByTargetBlockNumberWhenL2InclusiveBlockNumberToStopAndFlushAggregationSpecified() {
|
fun testValidAggrAndConflationByTargetBlockNumberWhenL2InclusiveBlockNumberToStopAndFlushAggregationSpecified() {
|
||||||
val aggregationConfigWithoutSwithBlockNumber = aggregationConfig.copy(
|
val aggregationConfigWithoutSwithBlockNumber = aggregationConfig.copy(
|
||||||
_targetEndBlocks = listOf(10L, 100L)
|
_targetEndBlocks = listOf(10L, 100L),
|
||||||
)
|
)
|
||||||
val conflationConfigWithTargetBlockNumber = conflationConfig.copy(
|
val conflationConfigWithTargetBlockNumber = conflationConfig.copy(
|
||||||
_conflationTargetEndBlockNumbers = listOf(100L)
|
_conflationTargetEndBlockNumbers = listOf(100L),
|
||||||
)
|
)
|
||||||
|
|
||||||
assertDoesNotThrow {
|
assertDoesNotThrow {
|
||||||
coordinatorConfig.copy(
|
coordinatorConfig.copy(
|
||||||
l2InclusiveBlockNumberToStopAndFlushAggregation = 100uL,
|
l2InclusiveBlockNumberToStopAndFlushAggregation = 100uL,
|
||||||
proofAggregation = aggregationConfigWithoutSwithBlockNumber,
|
proofAggregation = aggregationConfigWithoutSwithBlockNumber,
|
||||||
conflation = conflationConfigWithTargetBlockNumber
|
conflation = conflationConfigWithTargetBlockNumber,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,5 +168,5 @@ val expectedTimeOfDayMultipliers = mapOf(
|
|||||||
"SATURDAY_20" to 1.5073787902995706,
|
"SATURDAY_20" to 1.5073787902995706,
|
||||||
"SATURDAY_21" to 1.5605139580010123,
|
"SATURDAY_21" to 1.5605139580010123,
|
||||||
"SATURDAY_22" to 1.5885303316932382,
|
"SATURDAY_22" to 1.5885303316932382,
|
||||||
"SATURDAY_23" to 1.6169891066719597
|
"SATURDAY_23" to 1.6169891066719597,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -55,6 +55,6 @@ val expectedTracesLimitsV2 = TracesCountersV2(
|
|||||||
TracingModuleV2.BLOCK_KECCAK to 46u,
|
TracingModuleV2.BLOCK_KECCAK to 46u,
|
||||||
TracingModuleV2.BLOCK_L1_SIZE to 47u,
|
TracingModuleV2.BLOCK_L1_SIZE to 47u,
|
||||||
TracingModuleV2.BLOCK_L2_L1_LOGS to 48u,
|
TracingModuleV2.BLOCK_L2_L1_LOGS to 48u,
|
||||||
TracingModuleV2.BLOCK_TRANSACTIONS to 49u
|
TracingModuleV2.BLOCK_TRANSACTIONS to 49u,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import kotlin.time.toJavaDuration
|
|||||||
|
|
||||||
class L2NetworkGasPricingConfigTest {
|
class L2NetworkGasPricingConfigTest {
|
||||||
data class Config(
|
data class Config(
|
||||||
val l2NetworkGasPricing: L2NetworkGasPricingTomlDto
|
val l2NetworkGasPricing: L2NetworkGasPricingTomlDto,
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun parseConfig(toml: String): L2NetworkGasPricingTomlDto {
|
private fun parseConfig(toml: String): L2NetworkGasPricingTomlDto {
|
||||||
@@ -135,7 +135,7 @@ class L2NetworkGasPricingConfigTest {
|
|||||||
maxRetries = 3,
|
maxRetries = 3,
|
||||||
timeout = 6.seconds.toJavaDuration(),
|
timeout = 6.seconds.toJavaDuration(),
|
||||||
backoffDelay = 1.seconds.toJavaDuration(),
|
backoffDelay = 1.seconds.toJavaDuration(),
|
||||||
failuresWarningThreshold = 2
|
failuresWarningThreshold = 2,
|
||||||
),
|
),
|
||||||
|
|
||||||
priceUpdateInterval = Duration.parse("PT12S"),
|
priceUpdateInterval = Duration.parse("PT12S"),
|
||||||
@@ -152,29 +152,29 @@ class L2NetworkGasPricingConfigTest {
|
|||||||
naiveGasPricing = NaiveGasPricingTomlDto(
|
naiveGasPricing = NaiveGasPricingTomlDto(
|
||||||
baseFeeCoefficient = 0.1,
|
baseFeeCoefficient = 0.1,
|
||||||
priorityFeeCoefficient = 1.0,
|
priorityFeeCoefficient = 1.0,
|
||||||
baseFeeBlobCoefficient = 0.1
|
baseFeeBlobCoefficient = 0.1,
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
variableCostPricing = VariableCostPricingTomlDto(
|
variableCostPricing = VariableCostPricingTomlDto(
|
||||||
gasPriceFixedCost = 3000000u,
|
gasPriceFixedCost = 3000000u,
|
||||||
legacyFeesMultiplier = 1.2,
|
legacyFeesMultiplier = 1.2,
|
||||||
margin = 4.0,
|
margin = 4.0,
|
||||||
variableCostUpperBound = 10_000_000_001u,
|
variableCostUpperBound = 10_000_000_001u,
|
||||||
variableCostLowerBound = 90_000_001u
|
variableCostLowerBound = 90_000_001u,
|
||||||
),
|
),
|
||||||
jsonRpcPricingPropagation = JsonRpcPricingPropagationTomlDto(
|
jsonRpcPricingPropagation = JsonRpcPricingPropagationTomlDto(
|
||||||
gethGasPriceUpdateRecipients = listOf(
|
gethGasPriceUpdateRecipients = listOf(
|
||||||
URI("http://traces-node:8545/").toURL(),
|
URI("http://traces-node:8545/").toURL(),
|
||||||
URI("http://l2-node:8545/").toURL()
|
URI("http://l2-node:8545/").toURL(),
|
||||||
),
|
),
|
||||||
besuGasPriceUpdateRecipients = listOf(
|
besuGasPriceUpdateRecipients = listOf(
|
||||||
URI("http://sequencer:8545/").toURL()
|
URI("http://sequencer:8545/").toURL(),
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
extraDataPricingPropagation = ExtraDataPricingPropagationTomlDto(
|
extraDataPricingPropagation = ExtraDataPricingPropagationTomlDto(
|
||||||
extraDataUpdateRecipient = URI("http://sequencer:8545/").toURL()
|
extraDataUpdateRecipient = URI("http://sequencer:8545/").toURL(),
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +187,7 @@ class L2NetworkGasPricingConfigTest {
|
|||||||
maxRetries = 3,
|
maxRetries = 3,
|
||||||
timeout = 6.seconds.toJavaDuration(),
|
timeout = 6.seconds.toJavaDuration(),
|
||||||
backoffDelay = 1.seconds.toJavaDuration(),
|
backoffDelay = 1.seconds.toJavaDuration(),
|
||||||
failuresWarningThreshold = 2
|
failuresWarningThreshold = 2,
|
||||||
),
|
),
|
||||||
|
|
||||||
priceUpdateInterval = Duration.parse("PT12S"),
|
priceUpdateInterval = Duration.parse("PT12S"),
|
||||||
@@ -201,28 +201,28 @@ class L2NetworkGasPricingConfigTest {
|
|||||||
type = LegacyGasPricingTomlDto.Type.SampleTransaction,
|
type = LegacyGasPricingTomlDto.Type.SampleTransaction,
|
||||||
gasPriceUpperBound = 10_000_000_000u,
|
gasPriceUpperBound = 10_000_000_000u,
|
||||||
gasPriceLowerBound = 90_000_000u,
|
gasPriceLowerBound = 90_000_000u,
|
||||||
naiveGasPricing = null
|
naiveGasPricing = null,
|
||||||
),
|
),
|
||||||
variableCostPricing = VariableCostPricingTomlDto(
|
variableCostPricing = VariableCostPricingTomlDto(
|
||||||
gasPriceFixedCost = 3000000u,
|
gasPriceFixedCost = 3000000u,
|
||||||
legacyFeesMultiplier = 1.2,
|
legacyFeesMultiplier = 1.2,
|
||||||
margin = 4.0,
|
margin = 4.0,
|
||||||
variableCostUpperBound = 10_000_000_001u,
|
variableCostUpperBound = 10_000_000_001u,
|
||||||
variableCostLowerBound = 90_000_001u
|
variableCostLowerBound = 90_000_001u,
|
||||||
),
|
),
|
||||||
jsonRpcPricingPropagation = JsonRpcPricingPropagationTomlDto(
|
jsonRpcPricingPropagation = JsonRpcPricingPropagationTomlDto(
|
||||||
gethGasPriceUpdateRecipients = listOf(
|
gethGasPriceUpdateRecipients = listOf(
|
||||||
URI("http://traces-node:8545/").toURL(),
|
URI("http://traces-node:8545/").toURL(),
|
||||||
URI("http://l2-node:8545/").toURL()
|
URI("http://l2-node:8545/").toURL(),
|
||||||
),
|
),
|
||||||
besuGasPriceUpdateRecipients = listOf(
|
besuGasPriceUpdateRecipients = listOf(
|
||||||
URI("http://sequencer:8545/").toURL()
|
URI("http://sequencer:8545/").toURL(),
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
extraDataPricingPropagation = ExtraDataPricingPropagationTomlDto(
|
extraDataPricingPropagation = ExtraDataPricingPropagationTomlDto(
|
||||||
extraDataUpdateRecipient = URI("http://sequencer:8545/").toURL()
|
extraDataUpdateRecipient = URI("http://sequencer:8545/").toURL(),
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,14 +233,14 @@ class L2NetworkGasPricingConfigTest {
|
|||||||
maxRetries = 3u,
|
maxRetries = 3u,
|
||||||
timeout = 6.seconds,
|
timeout = 6.seconds,
|
||||||
backoffDelay = 1.seconds,
|
backoffDelay = 1.seconds,
|
||||||
failuresWarningThreshold = 2u
|
failuresWarningThreshold = 2u,
|
||||||
)
|
)
|
||||||
|
|
||||||
assertThat(config).isEqualTo(
|
assertThat(config).isEqualTo(
|
||||||
L2NetworkGasPricingService.Config(
|
L2NetworkGasPricingService.Config(
|
||||||
feeHistoryFetcherConfig = FeeHistoryFetcherImpl.Config(
|
feeHistoryFetcherConfig = FeeHistoryFetcherImpl.Config(
|
||||||
feeHistoryBlockCount = 50U,
|
feeHistoryBlockCount = 50U,
|
||||||
feeHistoryRewardPercentile = 15.0
|
feeHistoryRewardPercentile = 15.0,
|
||||||
),
|
),
|
||||||
legacy = L2NetworkGasPricingService.LegacyGasPricingCalculatorConfig(
|
legacy = L2NetworkGasPricingService.LegacyGasPricingCalculatorConfig(
|
||||||
naiveGasPricingCalculatorConfig = GasUsageRatioWeightedAverageFeesCalculator.Config(
|
naiveGasPricingCalculatorConfig = GasUsageRatioWeightedAverageFeesCalculator.Config(
|
||||||
@@ -248,24 +248,24 @@ class L2NetworkGasPricingConfigTest {
|
|||||||
priorityFeeCoefficient = 1.0,
|
priorityFeeCoefficient = 1.0,
|
||||||
baseFeeBlobCoefficient = 0.1,
|
baseFeeBlobCoefficient = 0.1,
|
||||||
blobSubmissionExpectedExecutionGas = 213_000,
|
blobSubmissionExpectedExecutionGas = 213_000,
|
||||||
expectedBlobGas = 131072
|
expectedBlobGas = 131072,
|
||||||
),
|
),
|
||||||
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
|
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
|
||||||
10_000_000_000.0,
|
10_000_000_000.0,
|
||||||
90_000_000.0,
|
90_000_000.0,
|
||||||
0.0
|
0.0,
|
||||||
),
|
),
|
||||||
transactionCostCalculatorConfig = null
|
transactionCostCalculatorConfig = null,
|
||||||
),
|
),
|
||||||
jsonRpcGasPriceUpdaterConfig = GasPriceUpdaterImpl.Config(
|
jsonRpcGasPriceUpdaterConfig = GasPriceUpdaterImpl.Config(
|
||||||
gethEndpoints = listOf(
|
gethEndpoints = listOf(
|
||||||
URI("http://traces-node:8545/").toURL(),
|
URI("http://traces-node:8545/").toURL(),
|
||||||
URI("http://l2-node:8545/").toURL()
|
URI("http://l2-node:8545/").toURL(),
|
||||||
),
|
),
|
||||||
besuEndPoints = listOf(
|
besuEndPoints = listOf(
|
||||||
URI("http://sequencer:8545/").toURL()
|
URI("http://sequencer:8545/").toURL(),
|
||||||
),
|
),
|
||||||
retryConfig = l2NetworkGasPricingRequestretryConfig
|
retryConfig = l2NetworkGasPricingRequestretryConfig,
|
||||||
),
|
),
|
||||||
jsonRpcPriceUpdateInterval = 12.seconds,
|
jsonRpcPriceUpdateInterval = 12.seconds,
|
||||||
extraDataPricingPropagationEnabled = true,
|
extraDataPricingPropagationEnabled = true,
|
||||||
@@ -274,22 +274,22 @@ class L2NetworkGasPricingConfigTest {
|
|||||||
blobSubmissionExpectedExecutionGas = 213_000u,
|
blobSubmissionExpectedExecutionGas = 213_000u,
|
||||||
bytesPerDataSubmission = 131072u,
|
bytesPerDataSubmission = 131072u,
|
||||||
expectedBlobGas = 131072u,
|
expectedBlobGas = 131072u,
|
||||||
margin = 4.0
|
margin = 4.0,
|
||||||
),
|
),
|
||||||
variableFeesCalculatorBounds = BoundableFeeCalculator.Config(
|
variableFeesCalculatorBounds = BoundableFeeCalculator.Config(
|
||||||
feeUpperBound = 10_000_000_001.0,
|
feeUpperBound = 10_000_000_001.0,
|
||||||
feeLowerBound = 90_000_001.0,
|
feeLowerBound = 90_000_001.0,
|
||||||
feeMargin = 0.0
|
feeMargin = 0.0,
|
||||||
),
|
),
|
||||||
extraDataCalculatorConfig = MinerExtraDataV1CalculatorImpl.Config(
|
extraDataCalculatorConfig = MinerExtraDataV1CalculatorImpl.Config(
|
||||||
fixedCostInKWei = 3000u,
|
fixedCostInKWei = 3000u,
|
||||||
ethGasPriceMultiplier = 1.2
|
ethGasPriceMultiplier = 1.2,
|
||||||
),
|
),
|
||||||
extraDataUpdaterConfig = ExtraDataV1UpdaterImpl.Config(
|
extraDataUpdaterConfig = ExtraDataV1UpdaterImpl.Config(
|
||||||
sequencerEndpoint = URI(/* str = */ "http://sequencer:8545/").toURL(),
|
sequencerEndpoint = URI("http://sequencer:8545/").toURL(),
|
||||||
retryConfig = l2NetworkGasPricingRequestretryConfig
|
retryConfig = l2NetworkGasPricingRequestretryConfig,
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,38 +300,38 @@ class L2NetworkGasPricingConfigTest {
|
|||||||
maxRetries = 3u,
|
maxRetries = 3u,
|
||||||
timeout = 6.seconds,
|
timeout = 6.seconds,
|
||||||
backoffDelay = 1.seconds,
|
backoffDelay = 1.seconds,
|
||||||
failuresWarningThreshold = 2u
|
failuresWarningThreshold = 2u,
|
||||||
)
|
)
|
||||||
|
|
||||||
assertThat(config).isEqualTo(
|
assertThat(config).isEqualTo(
|
||||||
L2NetworkGasPricingService.Config(
|
L2NetworkGasPricingService.Config(
|
||||||
feeHistoryFetcherConfig = FeeHistoryFetcherImpl.Config(
|
feeHistoryFetcherConfig = FeeHistoryFetcherImpl.Config(
|
||||||
feeHistoryBlockCount = 50U,
|
feeHistoryBlockCount = 50U,
|
||||||
feeHistoryRewardPercentile = 15.0
|
feeHistoryRewardPercentile = 15.0,
|
||||||
),
|
),
|
||||||
legacy = L2NetworkGasPricingService.LegacyGasPricingCalculatorConfig(
|
legacy = L2NetworkGasPricingService.LegacyGasPricingCalculatorConfig(
|
||||||
naiveGasPricingCalculatorConfig = null,
|
naiveGasPricingCalculatorConfig = null,
|
||||||
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
|
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
|
||||||
10_000_000_000.0,
|
10_000_000_000.0,
|
||||||
90_000_000.0,
|
90_000_000.0,
|
||||||
0.0
|
0.0,
|
||||||
),
|
),
|
||||||
transactionCostCalculatorConfig = TransactionCostCalculator.Config(
|
transactionCostCalculatorConfig = TransactionCostCalculator.Config(
|
||||||
sampleTransactionCostMultiplier = 1.0,
|
sampleTransactionCostMultiplier = 1.0,
|
||||||
fixedCostWei = 3000000u,
|
fixedCostWei = 3000000u,
|
||||||
compressedTxSize = 125,
|
compressedTxSize = 125,
|
||||||
expectedGas = 21000
|
expectedGas = 21000,
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
jsonRpcGasPriceUpdaterConfig = GasPriceUpdaterImpl.Config(
|
jsonRpcGasPriceUpdaterConfig = GasPriceUpdaterImpl.Config(
|
||||||
gethEndpoints = listOf(
|
gethEndpoints = listOf(
|
||||||
URI("http://traces-node:8545/").toURL(),
|
URI("http://traces-node:8545/").toURL(),
|
||||||
URI("http://l2-node:8545/").toURL()
|
URI("http://l2-node:8545/").toURL(),
|
||||||
),
|
),
|
||||||
besuEndPoints = listOf(
|
besuEndPoints = listOf(
|
||||||
URI("http://sequencer:8545/").toURL()
|
URI("http://sequencer:8545/").toURL(),
|
||||||
),
|
),
|
||||||
retryConfig = l2NetworkGasPricingRequestretryConfig
|
retryConfig = l2NetworkGasPricingRequestretryConfig,
|
||||||
),
|
),
|
||||||
jsonRpcPriceUpdateInterval = 12.seconds,
|
jsonRpcPriceUpdateInterval = 12.seconds,
|
||||||
extraDataPricingPropagationEnabled = true,
|
extraDataPricingPropagationEnabled = true,
|
||||||
@@ -340,22 +340,22 @@ class L2NetworkGasPricingConfigTest {
|
|||||||
blobSubmissionExpectedExecutionGas = 213_000u,
|
blobSubmissionExpectedExecutionGas = 213_000u,
|
||||||
bytesPerDataSubmission = 131072u,
|
bytesPerDataSubmission = 131072u,
|
||||||
expectedBlobGas = 131072u,
|
expectedBlobGas = 131072u,
|
||||||
margin = 4.0
|
margin = 4.0,
|
||||||
),
|
),
|
||||||
variableFeesCalculatorBounds = BoundableFeeCalculator.Config(
|
variableFeesCalculatorBounds = BoundableFeeCalculator.Config(
|
||||||
feeUpperBound = 10_000_000_001.0,
|
feeUpperBound = 10_000_000_001.0,
|
||||||
feeLowerBound = 90_000_001.0,
|
feeLowerBound = 90_000_001.0,
|
||||||
feeMargin = 0.0
|
feeMargin = 0.0,
|
||||||
),
|
),
|
||||||
extraDataCalculatorConfig = MinerExtraDataV1CalculatorImpl.Config(
|
extraDataCalculatorConfig = MinerExtraDataV1CalculatorImpl.Config(
|
||||||
fixedCostInKWei = 3000u,
|
fixedCostInKWei = 3000u,
|
||||||
ethGasPriceMultiplier = 1.2
|
ethGasPriceMultiplier = 1.2,
|
||||||
),
|
),
|
||||||
extraDataUpdaterConfig = ExtraDataV1UpdaterImpl.Config(
|
extraDataUpdaterConfig = ExtraDataV1UpdaterImpl.Config(
|
||||||
sequencerEndpoint = URI(/* str = */ "http://sequencer:8545/").toURL(),
|
sequencerEndpoint = URI("http://sequencer:8545/").toURL(),
|
||||||
retryConfig = l2NetworkGasPricingRequestretryConfig
|
retryConfig = l2NetworkGasPricingRequestretryConfig,
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,28 +400,28 @@ class L2NetworkGasPricingConfigTest {
|
|||||||
maxRetries = 3u,
|
maxRetries = 3u,
|
||||||
timeout = 6.seconds,
|
timeout = 6.seconds,
|
||||||
backoffDelay = 1.seconds,
|
backoffDelay = 1.seconds,
|
||||||
failuresWarningThreshold = 2u
|
failuresWarningThreshold = 2u,
|
||||||
)
|
)
|
||||||
|
|
||||||
assertThat(config).isEqualTo(
|
assertThat(config).isEqualTo(
|
||||||
L2NetworkGasPricingService.Config(
|
L2NetworkGasPricingService.Config(
|
||||||
feeHistoryFetcherConfig = FeeHistoryFetcherImpl.Config(
|
feeHistoryFetcherConfig = FeeHistoryFetcherImpl.Config(
|
||||||
feeHistoryBlockCount = 50U,
|
feeHistoryBlockCount = 50U,
|
||||||
feeHistoryRewardPercentile = 15.0
|
feeHistoryRewardPercentile = 15.0,
|
||||||
),
|
),
|
||||||
legacy = L2NetworkGasPricingService.LegacyGasPricingCalculatorConfig(
|
legacy = L2NetworkGasPricingService.LegacyGasPricingCalculatorConfig(
|
||||||
naiveGasPricingCalculatorConfig = null,
|
naiveGasPricingCalculatorConfig = null,
|
||||||
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
|
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
|
||||||
10_000_000_000.0,
|
10_000_000_000.0,
|
||||||
90_000_000.0,
|
90_000_000.0,
|
||||||
0.0
|
0.0,
|
||||||
),
|
),
|
||||||
transactionCostCalculatorConfig = TransactionCostCalculator.Config(
|
transactionCostCalculatorConfig = TransactionCostCalculator.Config(
|
||||||
sampleTransactionCostMultiplier = 1.0,
|
sampleTransactionCostMultiplier = 1.0,
|
||||||
fixedCostWei = 3000000u,
|
fixedCostWei = 3000000u,
|
||||||
compressedTxSize = 125,
|
compressedTxSize = 125,
|
||||||
expectedGas = 21000
|
expectedGas = 21000,
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
jsonRpcGasPriceUpdaterConfig = null,
|
jsonRpcGasPriceUpdaterConfig = null,
|
||||||
jsonRpcPriceUpdateInterval = 12.seconds,
|
jsonRpcPriceUpdateInterval = 12.seconds,
|
||||||
@@ -431,22 +431,22 @@ class L2NetworkGasPricingConfigTest {
|
|||||||
blobSubmissionExpectedExecutionGas = 213_000u,
|
blobSubmissionExpectedExecutionGas = 213_000u,
|
||||||
bytesPerDataSubmission = 131072u,
|
bytesPerDataSubmission = 131072u,
|
||||||
expectedBlobGas = 131072u,
|
expectedBlobGas = 131072u,
|
||||||
margin = 4.0
|
margin = 4.0,
|
||||||
),
|
),
|
||||||
variableFeesCalculatorBounds = BoundableFeeCalculator.Config(
|
variableFeesCalculatorBounds = BoundableFeeCalculator.Config(
|
||||||
feeUpperBound = 10_000_000_001.0,
|
feeUpperBound = 10_000_000_001.0,
|
||||||
feeLowerBound = 90_000_001.0,
|
feeLowerBound = 90_000_001.0,
|
||||||
feeMargin = 0.0
|
feeMargin = 0.0,
|
||||||
),
|
),
|
||||||
extraDataCalculatorConfig = MinerExtraDataV1CalculatorImpl.Config(
|
extraDataCalculatorConfig = MinerExtraDataV1CalculatorImpl.Config(
|
||||||
fixedCostInKWei = 3000u,
|
fixedCostInKWei = 3000u,
|
||||||
ethGasPriceMultiplier = 1.2
|
ethGasPriceMultiplier = 1.2,
|
||||||
),
|
),
|
||||||
extraDataUpdaterConfig = ExtraDataV1UpdaterImpl.Config(
|
extraDataUpdaterConfig = ExtraDataV1UpdaterImpl.Config(
|
||||||
sequencerEndpoint = URI(/* str = */ "http://sequencer:8545/").toURL(),
|
sequencerEndpoint = URI("http://sequencer:8545/").toURL(),
|
||||||
retryConfig = l2NetworkGasPricingRequestretryConfig
|
retryConfig = l2NetworkGasPricingRequestretryConfig,
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,28 +496,28 @@ class L2NetworkGasPricingConfigTest {
|
|||||||
maxRetries = 3u,
|
maxRetries = 3u,
|
||||||
timeout = 6.seconds,
|
timeout = 6.seconds,
|
||||||
backoffDelay = 1.seconds,
|
backoffDelay = 1.seconds,
|
||||||
failuresWarningThreshold = 2u
|
failuresWarningThreshold = 2u,
|
||||||
)
|
)
|
||||||
|
|
||||||
assertThat(config).isEqualTo(
|
assertThat(config).isEqualTo(
|
||||||
L2NetworkGasPricingService.Config(
|
L2NetworkGasPricingService.Config(
|
||||||
feeHistoryFetcherConfig = FeeHistoryFetcherImpl.Config(
|
feeHistoryFetcherConfig = FeeHistoryFetcherImpl.Config(
|
||||||
feeHistoryBlockCount = 50U,
|
feeHistoryBlockCount = 50U,
|
||||||
feeHistoryRewardPercentile = 15.0
|
feeHistoryRewardPercentile = 15.0,
|
||||||
),
|
),
|
||||||
legacy = L2NetworkGasPricingService.LegacyGasPricingCalculatorConfig(
|
legacy = L2NetworkGasPricingService.LegacyGasPricingCalculatorConfig(
|
||||||
naiveGasPricingCalculatorConfig = null,
|
naiveGasPricingCalculatorConfig = null,
|
||||||
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
|
legacyGasPricingCalculatorBounds = BoundableFeeCalculator.Config(
|
||||||
10_000_000_000.0,
|
10_000_000_000.0,
|
||||||
90_000_000.0,
|
90_000_000.0,
|
||||||
0.0
|
0.0,
|
||||||
),
|
),
|
||||||
transactionCostCalculatorConfig = TransactionCostCalculator.Config(
|
transactionCostCalculatorConfig = TransactionCostCalculator.Config(
|
||||||
sampleTransactionCostMultiplier = 1.0,
|
sampleTransactionCostMultiplier = 1.0,
|
||||||
fixedCostWei = 3000000u,
|
fixedCostWei = 3000000u,
|
||||||
compressedTxSize = 125,
|
compressedTxSize = 125,
|
||||||
expectedGas = 21000
|
expectedGas = 21000,
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
jsonRpcGasPriceUpdaterConfig = null,
|
jsonRpcGasPriceUpdaterConfig = null,
|
||||||
jsonRpcPriceUpdateInterval = 12.seconds,
|
jsonRpcPriceUpdateInterval = 12.seconds,
|
||||||
@@ -527,22 +527,22 @@ class L2NetworkGasPricingConfigTest {
|
|||||||
blobSubmissionExpectedExecutionGas = 213_000u,
|
blobSubmissionExpectedExecutionGas = 213_000u,
|
||||||
bytesPerDataSubmission = 131072u,
|
bytesPerDataSubmission = 131072u,
|
||||||
expectedBlobGas = 131072u,
|
expectedBlobGas = 131072u,
|
||||||
margin = 4.0
|
margin = 4.0,
|
||||||
),
|
),
|
||||||
variableFeesCalculatorBounds = BoundableFeeCalculator.Config(
|
variableFeesCalculatorBounds = BoundableFeeCalculator.Config(
|
||||||
feeUpperBound = 10_000_000_001.0,
|
feeUpperBound = 10_000_000_001.0,
|
||||||
feeLowerBound = 90_000_001.0,
|
feeLowerBound = 90_000_001.0,
|
||||||
feeMargin = 0.0
|
feeMargin = 0.0,
|
||||||
),
|
),
|
||||||
extraDataCalculatorConfig = MinerExtraDataV1CalculatorImpl.Config(
|
extraDataCalculatorConfig = MinerExtraDataV1CalculatorImpl.Config(
|
||||||
fixedCostInKWei = 3000u,
|
fixedCostInKWei = 3000u,
|
||||||
ethGasPriceMultiplier = 1.2
|
ethGasPriceMultiplier = 1.2,
|
||||||
),
|
),
|
||||||
extraDataUpdaterConfig = ExtraDataV1UpdaterImpl.Config(
|
extraDataUpdaterConfig = ExtraDataV1UpdaterImpl.Config(
|
||||||
sequencerEndpoint = URI(/* str = */ "http://sequencer:8545/").toURL(),
|
sequencerEndpoint = URI("http://sequencer:8545/").toURL(),
|
||||||
retryConfig = l2NetworkGasPricingRequestretryConfig
|
retryConfig = l2NetworkGasPricingRequestretryConfig,
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class MessageAnchoringConfigTest {
|
|||||||
private val l1DefaultEndpoint = URI("http://l1-default-rpc-endpoint:8545").toURL()
|
private val l1DefaultEndpoint = URI("http://l1-default-rpc-endpoint:8545").toURL()
|
||||||
private val l2DefaultEndpoint = URI("http://l2-default-rpc-endpoint:8545").toURL()
|
private val l2DefaultEndpoint = URI("http://l2-default-rpc-endpoint:8545").toURL()
|
||||||
data class Config(
|
data class Config(
|
||||||
val messageAnchoring: MessageAnchoringConfigTomlDto = MessageAnchoringConfigTomlDto()
|
val messageAnchoring: MessageAnchoringConfigTomlDto = MessageAnchoringConfigTomlDto(),
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun parseConfig(toml: String): MessageAnchoringConfig {
|
private fun parseConfig(toml: String): MessageAnchoringConfig {
|
||||||
@@ -27,7 +27,7 @@ class MessageAnchoringConfigTest {
|
|||||||
.let {
|
.let {
|
||||||
it.messageAnchoring.reified(
|
it.messageAnchoring.reified(
|
||||||
l1DefaultEndpoint = l1DefaultEndpoint,
|
l1DefaultEndpoint = l1DefaultEndpoint,
|
||||||
l2DefaultEndpoint = l2DefaultEndpoint
|
l2DefaultEndpoint = l2DefaultEndpoint,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,13 +74,13 @@ class MessageAnchoringConfigTest {
|
|||||||
maxRetries = 10u,
|
maxRetries = 10u,
|
||||||
timeout = 100.seconds,
|
timeout = 100.seconds,
|
||||||
backoffDelay = 11.seconds,
|
backoffDelay = 11.seconds,
|
||||||
failuresWarningThreshold = 1u
|
failuresWarningThreshold = 1u,
|
||||||
),
|
),
|
||||||
l2RequestRetryConfig = RetryConfig(
|
l2RequestRetryConfig = RetryConfig(
|
||||||
maxRetries = 20u,
|
maxRetries = 20u,
|
||||||
timeout = 200.seconds,
|
timeout = 200.seconds,
|
||||||
backoffDelay = 21.seconds,
|
backoffDelay = 21.seconds,
|
||||||
failuresWarningThreshold = 2u
|
failuresWarningThreshold = 2u,
|
||||||
),
|
),
|
||||||
l1EventPollingInterval = 30.seconds,
|
l1EventPollingInterval = 30.seconds,
|
||||||
l1EventPollingTimeout = 6.seconds,
|
l1EventPollingTimeout = 6.seconds,
|
||||||
@@ -88,8 +88,8 @@ class MessageAnchoringConfigTest {
|
|||||||
l1EventSearchBlockChunk = 123u,
|
l1EventSearchBlockChunk = 123u,
|
||||||
anchoringTickInterval = 3.seconds,
|
anchoringTickInterval = 3.seconds,
|
||||||
messageQueueCapacity = 321u,
|
messageQueueCapacity = 321u,
|
||||||
maxMessagesToAnchorPerL2Transaction = 54u
|
maxMessagesToAnchorPerL2Transaction = 54u,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,13 +111,13 @@ class MessageAnchoringConfigTest {
|
|||||||
maxRetries = null,
|
maxRetries = null,
|
||||||
timeout = null,
|
timeout = null,
|
||||||
backoffDelay = 1.seconds,
|
backoffDelay = 1.seconds,
|
||||||
failuresWarningThreshold = 3u
|
failuresWarningThreshold = 3u,
|
||||||
),
|
),
|
||||||
l2RequestRetryConfig = RetryConfig(
|
l2RequestRetryConfig = RetryConfig(
|
||||||
maxRetries = null,
|
maxRetries = null,
|
||||||
timeout = null,
|
timeout = null,
|
||||||
backoffDelay = 1.seconds,
|
backoffDelay = 1.seconds,
|
||||||
failuresWarningThreshold = 3u
|
failuresWarningThreshold = 3u,
|
||||||
),
|
),
|
||||||
l1EventPollingInterval = 12.seconds,
|
l1EventPollingInterval = 12.seconds,
|
||||||
l1EventPollingTimeout = 6.seconds,
|
l1EventPollingTimeout = 6.seconds,
|
||||||
@@ -125,8 +125,8 @@ class MessageAnchoringConfigTest {
|
|||||||
l1EventSearchBlockChunk = 1000u,
|
l1EventSearchBlockChunk = 1000u,
|
||||||
anchoringTickInterval = 2.seconds,
|
anchoringTickInterval = 2.seconds,
|
||||||
messageQueueCapacity = 10_000u,
|
messageQueueCapacity = 10_000u,
|
||||||
maxMessagesToAnchorPerL2Transaction = 100u
|
maxMessagesToAnchorPerL2Transaction = 100u,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import kotlin.time.Duration.Companion.seconds
|
|||||||
|
|
||||||
class ProverConfigTest {
|
class ProverConfigTest {
|
||||||
data class Config(
|
data class Config(
|
||||||
val prover: ProverConfigTomlDto
|
val prover: ProverConfigTomlDto,
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun parseConfig(toml: String): ProversConfig {
|
private fun parseConfig(toml: String): ProversConfig {
|
||||||
@@ -62,8 +62,8 @@ class ProverConfigTest {
|
|||||||
inprogressRequestWritingSuffix = ".OVERRIDE_inprogress_coordinator_writing",
|
inprogressRequestWritingSuffix = ".OVERRIDE_inprogress_coordinator_writing",
|
||||||
inprogressProvingSuffixPattern = "OVERRIDE_\\.inprogress\\.prover.*",
|
inprogressProvingSuffixPattern = "OVERRIDE_\\.inprogress\\.prover.*",
|
||||||
pollingInterval = 10.seconds,
|
pollingInterval = 10.seconds,
|
||||||
pollingTimeout = 10.minutes
|
pollingTimeout = 10.minutes,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
assertThat(config.blobCompression).isEqualTo(
|
assertThat(config.blobCompression).isEqualTo(
|
||||||
FileBasedProverConfig(
|
FileBasedProverConfig(
|
||||||
@@ -72,8 +72,8 @@ class ProverConfigTest {
|
|||||||
inprogressRequestWritingSuffix = ".inprogress_coordinator_writing",
|
inprogressRequestWritingSuffix = ".inprogress_coordinator_writing",
|
||||||
inprogressProvingSuffixPattern = "\\.inprogress\\.prover.*",
|
inprogressProvingSuffixPattern = "\\.inprogress\\.prover.*",
|
||||||
pollingInterval = 20.seconds,
|
pollingInterval = 20.seconds,
|
||||||
pollingTimeout = 20.minutes
|
pollingTimeout = 20.minutes,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
assertThat(config.proofAggregation).isEqualTo(
|
assertThat(config.proofAggregation).isEqualTo(
|
||||||
FileBasedProverConfig(
|
FileBasedProverConfig(
|
||||||
@@ -82,8 +82,8 @@ class ProverConfigTest {
|
|||||||
inprogressRequestWritingSuffix = ".inprogress_coordinator_writing",
|
inprogressRequestWritingSuffix = ".inprogress_coordinator_writing",
|
||||||
inprogressProvingSuffixPattern = "\\.inprogress\\.prover.*",
|
inprogressProvingSuffixPattern = "\\.inprogress\\.prover.*",
|
||||||
pollingInterval = 10.seconds,
|
pollingInterval = 10.seconds,
|
||||||
pollingTimeout = 10.minutes
|
pollingTimeout = 10.minutes,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,8 +122,8 @@ class ProverConfigTest {
|
|||||||
inprogressRequestWritingSuffix = ".NEW_OVERRIDE_2_inprogress_coordinator_writing",
|
inprogressRequestWritingSuffix = ".NEW_OVERRIDE_2_inprogress_coordinator_writing",
|
||||||
inprogressProvingSuffixPattern = "NEW_OVERRIDE_2\\.inprogress\\.prover.*",
|
inprogressProvingSuffixPattern = "NEW_OVERRIDE_2\\.inprogress\\.prover.*",
|
||||||
pollingInterval = 10.seconds,
|
pollingInterval = 10.seconds,
|
||||||
pollingTimeout = 5.minutes
|
pollingTimeout = 5.minutes,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
assertThat(config.proverB!!.blobCompression).isEqualTo(
|
assertThat(config.proverB!!.blobCompression).isEqualTo(
|
||||||
FileBasedProverConfig(
|
FileBasedProverConfig(
|
||||||
@@ -132,8 +132,8 @@ class ProverConfigTest {
|
|||||||
inprogressRequestWritingSuffix = ".NEW_OVERRIDE_inprogress_coordinator_writing",
|
inprogressRequestWritingSuffix = ".NEW_OVERRIDE_inprogress_coordinator_writing",
|
||||||
inprogressProvingSuffixPattern = "\\.inprogress\\.prover.*",
|
inprogressProvingSuffixPattern = "\\.inprogress\\.prover.*",
|
||||||
pollingInterval = 12.seconds,
|
pollingInterval = 12.seconds,
|
||||||
pollingTimeout = 12.minutes
|
pollingTimeout = 12.minutes,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
assertThat(config.proverB!!.proofAggregation).isEqualTo(
|
assertThat(config.proverB!!.proofAggregation).isEqualTo(
|
||||||
FileBasedProverConfig(
|
FileBasedProverConfig(
|
||||||
@@ -142,8 +142,8 @@ class ProverConfigTest {
|
|||||||
inprogressRequestWritingSuffix = ".NEW_OVERRIDE_inprogress_coordinator_writing",
|
inprogressRequestWritingSuffix = ".NEW_OVERRIDE_inprogress_coordinator_writing",
|
||||||
inprogressProvingSuffixPattern = "\\.inprogress\\.prover.*",
|
inprogressProvingSuffixPattern = "\\.inprogress\\.prover.*",
|
||||||
pollingInterval = 10.seconds,
|
pollingInterval = 10.seconds,
|
||||||
pollingTimeout = 5.minutes
|
pollingTimeout = 5.minutes,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class BlockCreationMonitorTest {
|
|||||||
pollingInterval = 100.milliseconds,
|
pollingInterval = 100.milliseconds,
|
||||||
blocksToFinalization = 2L,
|
blocksToFinalization = 2L,
|
||||||
blocksFetchLimit = 500,
|
blocksFetchLimit = 500,
|
||||||
lastL2BlockNumberToProcessInclusive = null
|
lastL2BlockNumberToProcessInclusive = null,
|
||||||
)
|
)
|
||||||
private lateinit var vertx: Vertx
|
private lateinit var vertx: Vertx
|
||||||
private lateinit var lastProvenBlockNumberProvider: LastProvenBlockNumberProviderDouble
|
private lateinit var lastProvenBlockNumberProvider: LastProvenBlockNumberProviderDouble
|
||||||
@@ -62,7 +62,7 @@ class BlockCreationMonitorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class LastProvenBlockNumberProviderDouble(
|
private class LastProvenBlockNumberProviderDouble(
|
||||||
initialValue: ULong
|
initialValue: ULong,
|
||||||
) : LastProvenBlockNumberProviderAsync {
|
) : LastProvenBlockNumberProviderAsync {
|
||||||
var lastProvenBlock: AtomicLong = AtomicLong(initialValue.toLong())
|
var lastProvenBlock: AtomicLong = AtomicLong(initialValue.toLong())
|
||||||
override fun getLastProvenBlockNumber(): SafeFuture<Long> {
|
override fun getLastProvenBlockNumber(): SafeFuture<Long> {
|
||||||
@@ -73,7 +73,7 @@ class BlockCreationMonitorTest {
|
|||||||
fun createBlockCreationMonitor(
|
fun createBlockCreationMonitor(
|
||||||
startingBlockNumberExclusive: Long = 99,
|
startingBlockNumberExclusive: Long = 99,
|
||||||
blockCreationListener: BlockCreationListener = this.blockCreationListener,
|
blockCreationListener: BlockCreationListener = this.blockCreationListener,
|
||||||
config: BlockCreationMonitor.Config = this.config
|
config: BlockCreationMonitor.Config = this.config,
|
||||||
): BlockCreationMonitor {
|
): BlockCreationMonitor {
|
||||||
return BlockCreationMonitor(
|
return BlockCreationMonitor(
|
||||||
this.vertx,
|
this.vertx,
|
||||||
@@ -81,7 +81,7 @@ class BlockCreationMonitorTest {
|
|||||||
startingBlockNumberExclusive = startingBlockNumberExclusive,
|
startingBlockNumberExclusive = startingBlockNumberExclusive,
|
||||||
blockCreationListener,
|
blockCreationListener,
|
||||||
lastProvenBlockNumberProvider,
|
lastProvenBlockNumberProvider,
|
||||||
config
|
config,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,14 +94,14 @@ class BlockCreationMonitorTest {
|
|||||||
fakeL2RpcNode = TestingJsonRpcServer(
|
fakeL2RpcNode = TestingJsonRpcServer(
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
recordRequestsResponses = true,
|
recordRequestsResponses = true,
|
||||||
responseObjectMapper = ethApiObjectMapper
|
responseObjectMapper = ethApiObjectMapper,
|
||||||
)
|
)
|
||||||
blockCreationListener = BlockCreationListenerDouble()
|
blockCreationListener = BlockCreationListenerDouble()
|
||||||
web3jClient = ExtendedWeb3JImpl(
|
web3jClient = ExtendedWeb3JImpl(
|
||||||
createWeb3jHttpClient(
|
createWeb3jHttpClient(
|
||||||
rpcUrl = "http://localhost:${fakeL2RpcNode.boundPort}",
|
rpcUrl = "http://localhost:${fakeL2RpcNode.boundPort}",
|
||||||
log = LogManager.getLogger("test.client.l2.web3j")
|
log = LogManager.getLogger("test.client.l2.web3j"),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
lastProvenBlockNumberProvider = LastProvenBlockNumberProviderDouble(99u)
|
lastProvenBlockNumberProvider = LastProvenBlockNumberProviderDouble(99u)
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ class BlockCreationMonitorTest {
|
|||||||
startBlockNumber: ULong,
|
startBlockNumber: ULong,
|
||||||
numberOfBlocks: Int,
|
numberOfBlocks: Int,
|
||||||
startBlockHash: ByteArray = ByteArrayExt.random32(),
|
startBlockHash: ByteArray = ByteArrayExt.random32(),
|
||||||
startBlockParentHash: ByteArray = ByteArrayExt.random32()
|
startBlockParentHash: ByteArray = ByteArrayExt.random32(),
|
||||||
): List<Block> {
|
): List<Block> {
|
||||||
var blockHash = startBlockHash
|
var blockHash = startBlockHash
|
||||||
var parentHash = startBlockParentHash
|
var parentHash = startBlockParentHash
|
||||||
@@ -124,7 +124,7 @@ class BlockCreationMonitorTest {
|
|||||||
createBlock(
|
createBlock(
|
||||||
number = startBlockNumber + i.toULong(),
|
number = startBlockNumber + i.toULong(),
|
||||||
hash = blockHash,
|
hash = blockHash,
|
||||||
parentHash = parentHash
|
parentHash = parentHash,
|
||||||
).also {
|
).also {
|
||||||
blockHash = ByteArrayExt.random32()
|
blockHash = ByteArrayExt.random32()
|
||||||
parentHash = it.hash
|
parentHash = it.hash
|
||||||
@@ -147,7 +147,7 @@ class BlockCreationMonitorTest {
|
|||||||
fun `should stop fetching blocks after lastBlockNumberInclusiveToProcess`() {
|
fun `should stop fetching blocks after lastBlockNumberInclusiveToProcess`() {
|
||||||
monitor = createBlockCreationMonitor(
|
monitor = createBlockCreationMonitor(
|
||||||
startingBlockNumberExclusive = 99,
|
startingBlockNumberExclusive = 99,
|
||||||
config = config.copy(lastL2BlockNumberToProcessInclusive = 103u)
|
config = config.copy(lastL2BlockNumberToProcessInclusive = 103u),
|
||||||
)
|
)
|
||||||
|
|
||||||
setupFakeExecutionLayerWithBlocks(createBlocks(startBlockNumber = 99u, numberOfBlocks = 20))
|
setupFakeExecutionLayerWithBlocks(createBlocks(startBlockNumber = 99u, numberOfBlocks = 20))
|
||||||
@@ -170,7 +170,7 @@ class BlockCreationMonitorTest {
|
|||||||
fun `should notify lister only after block is considered final on L2`() {
|
fun `should notify lister only after block is considered final on L2`() {
|
||||||
monitor = createBlockCreationMonitor(
|
monitor = createBlockCreationMonitor(
|
||||||
startingBlockNumberExclusive = 99,
|
startingBlockNumberExclusive = 99,
|
||||||
config = config.copy(blocksToFinalization = 2, blocksFetchLimit = 500)
|
config = config.copy(blocksToFinalization = 2, blocksFetchLimit = 500),
|
||||||
)
|
)
|
||||||
|
|
||||||
setupFakeExecutionLayerWithBlocks(createBlocks(startBlockNumber = 99u, numberOfBlocks = 200))
|
setupFakeExecutionLayerWithBlocks(createBlocks(startBlockNumber = 99u, numberOfBlocks = 200))
|
||||||
@@ -217,7 +217,7 @@ class BlockCreationMonitorTest {
|
|||||||
monitor = createBlockCreationMonitor(
|
monitor = createBlockCreationMonitor(
|
||||||
startingBlockNumberExclusive = 99,
|
startingBlockNumberExclusive = 99,
|
||||||
blockCreationListener = fakeBuggyLister,
|
blockCreationListener = fakeBuggyLister,
|
||||||
config = config.copy(blocksToFinalization = 2, lastL2BlockNumberToProcessInclusive = 112u)
|
config = config.copy(blocksToFinalization = 2, lastL2BlockNumberToProcessInclusive = 112u),
|
||||||
)
|
)
|
||||||
|
|
||||||
setupFakeExecutionLayerWithBlocks(createBlocks(startBlockNumber = 99u, numberOfBlocks = 20))
|
setupFakeExecutionLayerWithBlocks(createBlocks(startBlockNumber = 99u, numberOfBlocks = 20))
|
||||||
@@ -232,14 +232,14 @@ class BlockCreationMonitorTest {
|
|||||||
|
|
||||||
// assert it got block only once and in order
|
// assert it got block only once and in order
|
||||||
assertThat(blockCreationListener.blocksReceived.map { it.number }).containsExactly(
|
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
|
@Test
|
||||||
fun `should be resilient to connection failures`() {
|
fun `should be resilient to connection failures`() {
|
||||||
monitor = createBlockCreationMonitor(
|
monitor = createBlockCreationMonitor(
|
||||||
startingBlockNumberExclusive = 99
|
startingBlockNumberExclusive = 99,
|
||||||
)
|
)
|
||||||
|
|
||||||
setupFakeExecutionLayerWithBlocks(createBlocks(startBlockNumber = 99u, numberOfBlocks = 200))
|
setupFakeExecutionLayerWithBlocks(createBlocks(startBlockNumber = 99u, numberOfBlocks = 200))
|
||||||
@@ -268,7 +268,7 @@ class BlockCreationMonitorTest {
|
|||||||
@Test
|
@Test
|
||||||
fun `should stop when reorg is detected above blocksToFinalization limit - manual intervention necessary`() {
|
fun `should stop when reorg is detected above blocksToFinalization limit - manual intervention necessary`() {
|
||||||
monitor = createBlockCreationMonitor(
|
monitor = createBlockCreationMonitor(
|
||||||
startingBlockNumberExclusive = 99
|
startingBlockNumberExclusive = 99,
|
||||||
)
|
)
|
||||||
|
|
||||||
// simulate reorg by changing parent hash of block 105
|
// 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`() {
|
fun `should poll in order when response takes longer that polling interval`() {
|
||||||
monitor = createBlockCreationMonitor(
|
monitor = createBlockCreationMonitor(
|
||||||
startingBlockNumberExclusive = 99,
|
startingBlockNumberExclusive = 99,
|
||||||
config = config.copy(pollingInterval = 100.milliseconds)
|
config = config.copy(pollingInterval = 100.milliseconds),
|
||||||
)
|
)
|
||||||
|
|
||||||
val blocks = createBlocks(startBlockNumber = 99u, numberOfBlocks = 20)
|
val blocks = createBlocks(startBlockNumber = 99u, numberOfBlocks = 20)
|
||||||
@@ -318,7 +318,7 @@ class BlockCreationMonitorTest {
|
|||||||
102UL,
|
102UL,
|
||||||
103UL,
|
103UL,
|
||||||
104UL,
|
104UL,
|
||||||
105UL
|
105UL,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -326,7 +326,7 @@ class BlockCreationMonitorTest {
|
|||||||
@Test
|
@Test
|
||||||
fun `start allow 2nd call when already started`() {
|
fun `start allow 2nd call when already started`() {
|
||||||
monitor = createBlockCreationMonitor(
|
monitor = createBlockCreationMonitor(
|
||||||
startingBlockNumberExclusive = 99
|
startingBlockNumberExclusive = 99,
|
||||||
)
|
)
|
||||||
setupFakeExecutionLayerWithBlocks(createBlocks(startBlockNumber = 99u, numberOfBlocks = 5))
|
setupFakeExecutionLayerWithBlocks(createBlocks(startBlockNumber = 99u, numberOfBlocks = 5))
|
||||||
monitor.start().get()
|
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`() {
|
fun `should stop fetching blocks when gap is greater than fetch limit and resume upon catchup`() {
|
||||||
monitor = createBlockCreationMonitor(
|
monitor = createBlockCreationMonitor(
|
||||||
startingBlockNumberExclusive = 99,
|
startingBlockNumberExclusive = 99,
|
||||||
config = config.copy(blocksToFinalization = 0, blocksFetchLimit = 5)
|
config = config.copy(blocksToFinalization = 0, blocksFetchLimit = 5),
|
||||||
)
|
)
|
||||||
|
|
||||||
setupFakeExecutionLayerWithBlocks(createBlocks(startBlockNumber = 99u, numberOfBlocks = 30))
|
setupFakeExecutionLayerWithBlocks(createBlocks(startBlockNumber = 99u, numberOfBlocks = 30))
|
||||||
|
|||||||
@@ -27,23 +27,23 @@ class ConsecutiveProvenBlobsProviderWithLastEndBlockNumberTrackerTest {
|
|||||||
endBlockNumber = 2UL,
|
endBlockNumber = 2UL,
|
||||||
startBlockTimestamp = Instant.DISTANT_PAST,
|
startBlockTimestamp = Instant.DISTANT_PAST,
|
||||||
endBlockTimestamp = Instant.DISTANT_PAST,
|
endBlockTimestamp = Instant.DISTANT_PAST,
|
||||||
expectedShnarf = Random.nextBytes(32)
|
expectedShnarf = Random.nextBytes(32),
|
||||||
)
|
)
|
||||||
val baseBlobAndBatchCounters = BlobAndBatchCounters(
|
val baseBlobAndBatchCounters = BlobAndBatchCounters(
|
||||||
blobCounters = baseBlobCounters,
|
blobCounters = baseBlobCounters,
|
||||||
executionProofs = BlockIntervals(1UL, listOf(2UL, 3UL))
|
executionProofs = BlockIntervals(1UL, listOf(2UL, 3UL)),
|
||||||
)
|
)
|
||||||
val expectedEndBLockNumber = 10UL
|
val expectedEndBLockNumber = 10UL
|
||||||
val lastBlobAndBatchCounters = baseBlobAndBatchCounters.copy(
|
val lastBlobAndBatchCounters = baseBlobAndBatchCounters.copy(
|
||||||
blobCounters = baseBlobCounters.copy(startBlockNumber = 3UL, endBlockNumber = expectedEndBLockNumber)
|
blobCounters = baseBlobCounters.copy(startBlockNumber = 3UL, endBlockNumber = expectedEndBLockNumber),
|
||||||
)
|
)
|
||||||
whenever(repositoryMock.findConsecutiveProvenBlobs(any())).thenReturn(
|
whenever(repositoryMock.findConsecutiveProvenBlobs(any())).thenReturn(
|
||||||
SafeFuture.completedFuture(
|
SafeFuture.completedFuture(
|
||||||
listOf(
|
listOf(
|
||||||
baseBlobAndBatchCounters,
|
baseBlobAndBatchCounters,
|
||||||
lastBlobAndBatchCounters
|
lastBlobAndBatchCounters,
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
cache.findConsecutiveProvenBlobs(expectedEndBLockNumber.toLong())
|
cache.findConsecutiveProvenBlobs(expectedEndBLockNumber.toLong())
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ class ForkChoiceUpdaterImplTest {
|
|||||||
fun dispatchFinalizedBlockNotification_allClientsSuccess() {
|
fun dispatchFinalizedBlockNotification_allClientsSuccess() {
|
||||||
val mockClient1 = mock<RollupForkChoiceUpdatedClient>()
|
val mockClient1 = mock<RollupForkChoiceUpdatedClient>()
|
||||||
whenever(
|
whenever(
|
||||||
mockClient1.rollupForkChoiceUpdated(any())
|
mockClient1.rollupForkChoiceUpdated(any()),
|
||||||
)
|
)
|
||||||
.thenReturn(SafeFuture.completedFuture(Ok(RollupForkChoiceUpdatedResponse("success"))))
|
.thenReturn(SafeFuture.completedFuture(Ok(RollupForkChoiceUpdatedResponse("success"))))
|
||||||
val mockClient2 = mock<RollupForkChoiceUpdatedClient>()
|
val mockClient2 = mock<RollupForkChoiceUpdatedClient>()
|
||||||
whenever(
|
whenever(
|
||||||
mockClient2.rollupForkChoiceUpdated(any())
|
mockClient2.rollupForkChoiceUpdated(any()),
|
||||||
)
|
)
|
||||||
.thenReturn(SafeFuture.completedFuture(Ok(RollupForkChoiceUpdatedResponse("success"))))
|
.thenReturn(SafeFuture.completedFuture(Ok(RollupForkChoiceUpdatedResponse("success"))))
|
||||||
|
|
||||||
@@ -43,12 +43,12 @@ class ForkChoiceUpdaterImplTest {
|
|||||||
fun dispatchFinalizedBlockNotification_someClientsFail() {
|
fun dispatchFinalizedBlockNotification_someClientsFail() {
|
||||||
val mockClient1 = mock<RollupForkChoiceUpdatedClient>()
|
val mockClient1 = mock<RollupForkChoiceUpdatedClient>()
|
||||||
whenever(
|
whenever(
|
||||||
mockClient1.rollupForkChoiceUpdated(any())
|
mockClient1.rollupForkChoiceUpdated(any()),
|
||||||
)
|
)
|
||||||
.thenReturn(SafeFuture.completedFuture(Ok(RollupForkChoiceUpdatedResponse("success"))))
|
.thenReturn(SafeFuture.completedFuture(Ok(RollupForkChoiceUpdatedResponse("success"))))
|
||||||
val mockClient2 = mock<RollupForkChoiceUpdatedClient>()
|
val mockClient2 = mock<RollupForkChoiceUpdatedClient>()
|
||||||
whenever(
|
whenever(
|
||||||
mockClient2.rollupForkChoiceUpdated(any())
|
mockClient2.rollupForkChoiceUpdated(any()),
|
||||||
)
|
)
|
||||||
.thenReturn(SafeFuture.completedFuture(Err(ErrorResponse(RollupForkChoiceUpdatedError.UNKNOWN, ""))))
|
.thenReturn(SafeFuture.completedFuture(Err(ErrorResponse(RollupForkChoiceUpdatedError.UNKNOWN, ""))))
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class SimpleCompositeSafeFutureHandlerTest {
|
|||||||
handler2Calls.add("handler2:$value")
|
handler2Calls.add("handler2:$value")
|
||||||
SafeFuture.failedFuture(RuntimeException("Handler 2 failed"))
|
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)
|
SimpleCompositeSafeFutureHandler(handlers).invoke(123)
|
||||||
@@ -34,8 +34,11 @@ class SimpleCompositeSafeFutureHandlerTest {
|
|||||||
val handler3Calls = mutableListOf<String>()
|
val handler3Calls = mutableListOf<String>()
|
||||||
val handlers = listOf(
|
val handlers = listOf(
|
||||||
{ value: Long -> SafeFuture.completedFuture(handler1Calls.add("handler1:$value")) },
|
{ value: Long -> SafeFuture.completedFuture(handler1Calls.add("handler1:$value")) },
|
||||||
{ value: Long -> handler2Calls.add("handler2:$value"); throw RuntimeException("Forced error") },
|
{ value: Long ->
|
||||||
{ value: Long -> SafeFuture.completedFuture(handler3Calls.add("handler3:$value")) }
|
handler2Calls.add("handler2:$value")
|
||||||
|
throw RuntimeException("Forced error")
|
||||||
|
},
|
||||||
|
{ value: Long -> SafeFuture.completedFuture(handler3Calls.add("handler3:$value")) },
|
||||||
)
|
)
|
||||||
|
|
||||||
SimpleCompositeSafeFutureHandler(handlers).invoke(123)
|
SimpleCompositeSafeFutureHandler(handlers).invoke(123)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import net.consensys.zkevm.coordinator.clients.ProverClient
|
|||||||
import tech.pegasys.teku.infrastructure.async.SafeFuture
|
import tech.pegasys.teku.infrastructure.async.SafeFuture
|
||||||
|
|
||||||
class StartBlockNumberBasedSwitchPredicate<ProofRequest>(
|
class StartBlockNumberBasedSwitchPredicate<ProofRequest>(
|
||||||
private val switchStartBlockNumberInclusive: ULong
|
private val switchStartBlockNumberInclusive: ULong,
|
||||||
) where ProofRequest : BlockInterval {
|
) where ProofRequest : BlockInterval {
|
||||||
fun invoke(proofRequest: ProofRequest): Boolean = proofRequest.startBlockNumber >= switchStartBlockNumberInclusive
|
fun invoke(proofRequest: ProofRequest): Boolean = proofRequest.startBlockNumber >= switchStartBlockNumberInclusive
|
||||||
}
|
}
|
||||||
@@ -13,7 +13,7 @@ class StartBlockNumberBasedSwitchPredicate<ProofRequest>(
|
|||||||
class ABProverClientRouter<ProofRequest, ProofResponse>(
|
class ABProverClientRouter<ProofRequest, ProofResponse>(
|
||||||
private val proverA: ProverClient<ProofRequest, ProofResponse>,
|
private val proverA: ProverClient<ProofRequest, ProofResponse>,
|
||||||
private val proverB: ProverClient<ProofRequest, ProofResponse>,
|
private val proverB: ProverClient<ProofRequest, ProofResponse>,
|
||||||
private val switchToProverBPredicate: (ProofRequest) -> Boolean
|
private val switchToProverBPredicate: (ProofRequest) -> Boolean,
|
||||||
) : ProverClient<ProofRequest, ProofResponse> {
|
) : ProverClient<ProofRequest, ProofResponse> {
|
||||||
|
|
||||||
override fun requestProof(proofRequest: ProofRequest): SafeFuture<ProofResponse> {
|
override fun requestProof(proofRequest: ProofRequest): SafeFuture<ProofResponse> {
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import kotlin.time.Duration
|
|||||||
data class ProversConfig(
|
data class ProversConfig(
|
||||||
val proverA: ProverConfig,
|
val proverA: ProverConfig,
|
||||||
val switchBlockNumberInclusive: ULong?,
|
val switchBlockNumberInclusive: ULong?,
|
||||||
val proverB: ProverConfig?
|
val proverB: ProverConfig?,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class ProverConfig(
|
data class ProverConfig(
|
||||||
val execution: FileBasedProverConfig,
|
val execution: FileBasedProverConfig,
|
||||||
val blobCompression: FileBasedProverConfig,
|
val blobCompression: FileBasedProverConfig,
|
||||||
val proofAggregation: FileBasedProverConfig
|
val proofAggregation: FileBasedProverConfig,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class FileBasedProverConfig(
|
data class FileBasedProverConfig(
|
||||||
@@ -21,5 +21,5 @@ data class FileBasedProverConfig(
|
|||||||
val inprogressProvingSuffixPattern: String,
|
val inprogressProvingSuffixPattern: String,
|
||||||
val inprogressRequestWritingSuffix: String,
|
val inprogressRequestWritingSuffix: String,
|
||||||
val pollingInterval: Duration,
|
val pollingInterval: Duration,
|
||||||
val pollingTimeout: Duration
|
val pollingTimeout: Duration,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -28,13 +28,13 @@ import tech.pegasys.teku.infrastructure.async.SafeFuture
|
|||||||
class FileBasedBlobCompressionProverClientV2(
|
class FileBasedBlobCompressionProverClientV2(
|
||||||
val config: FileBasedProverConfig,
|
val config: FileBasedProverConfig,
|
||||||
val vertx: Vertx,
|
val vertx: Vertx,
|
||||||
jsonObjectMapper: ObjectMapper = JsonSerialization.proofResponseMapperV1
|
jsonObjectMapper: ObjectMapper = JsonSerialization.proofResponseMapperV1,
|
||||||
) :
|
) :
|
||||||
GenericFileBasedProverClient<
|
GenericFileBasedProverClient<
|
||||||
BlobCompressionProofRequest,
|
BlobCompressionProofRequest,
|
||||||
BlobCompressionProof,
|
BlobCompressionProof,
|
||||||
BlobCompressionProofJsonRequest,
|
BlobCompressionProofJsonRequest,
|
||||||
BlobCompressionProofJsonResponse
|
BlobCompressionProofJsonResponse,
|
||||||
>(
|
>(
|
||||||
config = config,
|
config = config,
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
@@ -42,7 +42,7 @@ class FileBasedBlobCompressionProverClientV2(
|
|||||||
fileReader = FileReader(
|
fileReader = FileReader(
|
||||||
vertx,
|
vertx,
|
||||||
jsonObjectMapper,
|
jsonObjectMapper,
|
||||||
BlobCompressionProofJsonResponse::class.java
|
BlobCompressionProofJsonResponse::class.java,
|
||||||
),
|
),
|
||||||
requestFileNameProvider = CompressionProofRequestFileNameProvider,
|
requestFileNameProvider = CompressionProofRequestFileNameProvider,
|
||||||
responseFileNameProvider = CompressionProofResponseFileNameProvider,
|
responseFileNameProvider = CompressionProofResponseFileNameProvider,
|
||||||
@@ -50,7 +50,7 @@ class FileBasedBlobCompressionProverClientV2(
|
|||||||
requestMapper = FileBasedBlobCompressionProverClientV2::requestDtoMapper,
|
requestMapper = FileBasedBlobCompressionProverClientV2::requestDtoMapper,
|
||||||
responseMapper = BlobCompressionProofJsonResponse::toDomainObject,
|
responseMapper = BlobCompressionProofJsonResponse::toDomainObject,
|
||||||
proofTypeLabel = "blob",
|
proofTypeLabel = "blob",
|
||||||
log = LogManager.getLogger(this::class.java)
|
log = LogManager.getLogger(this::class.java),
|
||||||
),
|
),
|
||||||
BlobCompressionProverClientV2 {
|
BlobCompressionProverClientV2 {
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ class FileBasedBlobCompressionProverClientV2(
|
|||||||
return ProofIndex(
|
return ProofIndex(
|
||||||
startBlockNumber = request.startBlockNumber,
|
startBlockNumber = request.startBlockNumber,
|
||||||
endBlockNumber = request.endBlockNumber,
|
endBlockNumber = request.endBlockNumber,
|
||||||
hash = request.expectedShnarfResult.expectedShnarf
|
hash = request.expectedShnarfResult.expectedShnarf,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ data class BatchExecutionProofRequestDto(
|
|||||||
val tracesEngineVersion: String,
|
val tracesEngineVersion: String,
|
||||||
val type2StateManagerVersion: String?,
|
val type2StateManagerVersion: String?,
|
||||||
val zkStateMerkleProof: ArrayNode,
|
val zkStateMerkleProof: ArrayNode,
|
||||||
val blocksData: List<RlpBridgeLogsDto>
|
val blocksData: List<RlpBridgeLogsDto>,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class RlpBridgeLogsDto(val rlp: String, val bridgeLogs: List<BridgeLogsDto>)
|
data class RlpBridgeLogsDto(val rlp: String, val bridgeLogs: List<BridgeLogsDto>)
|
||||||
@@ -40,7 +40,7 @@ data class BridgeLogsDto(
|
|||||||
val blockNumber: String,
|
val blockNumber: String,
|
||||||
val address: String,
|
val address: String,
|
||||||
val data: String,
|
val data: String,
|
||||||
val topics: List<String>
|
val topics: List<String>,
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
fun fromDomainObject(ethLog: EthLog): BridgeLogsDto {
|
fun fromDomainObject(ethLog: EthLog): BridgeLogsDto {
|
||||||
@@ -53,14 +53,14 @@ data class BridgeLogsDto(
|
|||||||
blockNumber = ethLog.blockNumber.toHexString(),
|
blockNumber = ethLog.blockNumber.toHexString(),
|
||||||
address = ethLog.address.encodeHex(),
|
address = ethLog.address.encodeHex(),
|
||||||
data = ethLog.data.encodeHex(),
|
data = ethLog.data.encodeHex(),
|
||||||
topics = ethLog.topics.map { it.encodeHex() }
|
topics = ethLog.topics.map { it.encodeHex() },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ExecutionProofRequestDtoMapper(
|
internal class ExecutionProofRequestDtoMapper(
|
||||||
private val encoder: BlockEncoder = BlockRLPEncoder
|
private val encoder: BlockEncoder = BlockRLPEncoder,
|
||||||
) : (BatchExecutionProofRequestV1) -> SafeFuture<BatchExecutionProofRequestDto> {
|
) : (BatchExecutionProofRequestV1) -> SafeFuture<BatchExecutionProofRequestDto> {
|
||||||
override fun invoke(request: BatchExecutionProofRequestV1): SafeFuture<BatchExecutionProofRequestDto> {
|
override fun invoke(request: BatchExecutionProofRequestV1): SafeFuture<BatchExecutionProofRequestDto> {
|
||||||
val blocksData = request.blocks.map { block ->
|
val blocksData = request.blocks.map { block ->
|
||||||
@@ -79,8 +79,8 @@ internal class ExecutionProofRequestDtoMapper(
|
|||||||
tracesEngineVersion = request.tracesResponse.tracesEngineVersion,
|
tracesEngineVersion = request.tracesResponse.tracesEngineVersion,
|
||||||
type2StateManagerVersion = request.type2StateData.zkStateManagerVersion,
|
type2StateManagerVersion = request.type2StateData.zkStateManagerVersion,
|
||||||
zkStateMerkleProof = request.type2StateData.zkStateMerkleProof,
|
zkStateMerkleProof = request.type2StateData.zkStateMerkleProof,
|
||||||
blocksData = blocksData
|
blocksData = blocksData,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,15 +105,15 @@ class FileBasedExecutionProverClientV2(
|
|||||||
executionProofRequestFileNameProvider: ProverFileNameProvider =
|
executionProofRequestFileNameProvider: ProverFileNameProvider =
|
||||||
ExecutionProofRequestFileNameProvider(
|
ExecutionProofRequestFileNameProvider(
|
||||||
tracesVersion = tracesVersion,
|
tracesVersion = tracesVersion,
|
||||||
stateManagerVersion = stateManagerVersion
|
stateManagerVersion = stateManagerVersion,
|
||||||
),
|
),
|
||||||
executionProofResponseFileNameProvider: ProverFileNameProvider = ExecutionProofResponseFileNameProvider
|
executionProofResponseFileNameProvider: ProverFileNameProvider = ExecutionProofResponseFileNameProvider,
|
||||||
) :
|
) :
|
||||||
GenericFileBasedProverClient<
|
GenericFileBasedProverClient<
|
||||||
BatchExecutionProofRequestV1,
|
BatchExecutionProofRequestV1,
|
||||||
BatchExecutionProofResponse,
|
BatchExecutionProofResponse,
|
||||||
BatchExecutionProofRequestDto,
|
BatchExecutionProofRequestDto,
|
||||||
Any
|
Any,
|
||||||
>(
|
>(
|
||||||
config = config,
|
config = config,
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
@@ -125,19 +125,19 @@ class FileBasedExecutionProverClientV2(
|
|||||||
requestMapper = ExecutionProofRequestDtoMapper(),
|
requestMapper = ExecutionProofRequestDtoMapper(),
|
||||||
responseMapper = { throw UnsupportedOperationException("Batch execution proof response shall not be parsed!") },
|
responseMapper = { throw UnsupportedOperationException("Batch execution proof response shall not be parsed!") },
|
||||||
proofTypeLabel = "batch",
|
proofTypeLabel = "batch",
|
||||||
log = LogManager.getLogger(FileBasedExecutionProverClientV2::class.java)
|
log = LogManager.getLogger(FileBasedExecutionProverClientV2::class.java),
|
||||||
),
|
),
|
||||||
ExecutionProverClientV2 {
|
ExecutionProverClientV2 {
|
||||||
|
|
||||||
override fun parseResponse(
|
override fun parseResponse(
|
||||||
responseFilePath: Path,
|
responseFilePath: Path,
|
||||||
proofIndex: ProofIndex
|
proofIndex: ProofIndex,
|
||||||
): SafeFuture<BatchExecutionProofResponse> {
|
): SafeFuture<BatchExecutionProofResponse> {
|
||||||
return SafeFuture.completedFuture(
|
return SafeFuture.completedFuture(
|
||||||
BatchExecutionProofResponse(
|
BatchExecutionProofResponse(
|
||||||
startBlockNumber = proofIndex.startBlockNumber,
|
startBlockNumber = proofIndex.startBlockNumber,
|
||||||
endBlockNumber = proofIndex.endBlockNumber
|
endBlockNumber = proofIndex.endBlockNumber,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,13 +21,13 @@ data class AggregationProofRequestDto(
|
|||||||
val compressionProofs: List<String>,
|
val compressionProofs: List<String>,
|
||||||
val parentAggregationLastBlockTimestamp: Long,
|
val parentAggregationLastBlockTimestamp: Long,
|
||||||
val parentAggregationLastL1RollingHashMessageNumber: Long,
|
val parentAggregationLastL1RollingHashMessageNumber: Long,
|
||||||
val parentAggregationLastL1RollingHash: String
|
val parentAggregationLastL1RollingHash: String,
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
fun fromDomainObject(
|
fun fromDomainObject(
|
||||||
proofsToAggregate: ProofsToAggregate,
|
proofsToAggregate: ProofsToAggregate,
|
||||||
executionProofResponseFileNameProvider: ProverFileNameProvider,
|
executionProofResponseFileNameProvider: ProverFileNameProvider,
|
||||||
compressionProofResponseFileNameProvider: ProverFileNameProvider
|
compressionProofResponseFileNameProvider: ProverFileNameProvider,
|
||||||
): AggregationProofRequestDto {
|
): AggregationProofRequestDto {
|
||||||
val executionProofsResponseFiles = proofsToAggregate.executionProofs
|
val executionProofsResponseFiles = proofsToAggregate.executionProofs
|
||||||
.toIntervalList()
|
.toIntervalList()
|
||||||
@@ -35,8 +35,8 @@ data class AggregationProofRequestDto(
|
|||||||
executionProofResponseFileNameProvider.getFileName(
|
executionProofResponseFileNameProvider.getFileName(
|
||||||
ProofIndex(
|
ProofIndex(
|
||||||
startBlockNumber = blockInterval.startBlockNumber,
|
startBlockNumber = blockInterval.startBlockNumber,
|
||||||
endBlockNumber = blockInterval.endBlockNumber
|
endBlockNumber = blockInterval.endBlockNumber,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,8 +46,8 @@ data class AggregationProofRequestDto(
|
|||||||
ProofIndex(
|
ProofIndex(
|
||||||
startBlockNumber = it.startBlockNumber,
|
startBlockNumber = it.startBlockNumber,
|
||||||
endBlockNumber = it.endBlockNumber,
|
endBlockNumber = it.endBlockNumber,
|
||||||
hash = it.hash
|
hash = it.hash,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ data class AggregationProofRequestDto(
|
|||||||
parentAggregationLastBlockTimestamp = proofsToAggregate.parentAggregationLastBlockTimestamp.epochSeconds,
|
parentAggregationLastBlockTimestamp = proofsToAggregate.parentAggregationLastBlockTimestamp.epochSeconds,
|
||||||
parentAggregationLastL1RollingHashMessageNumber =
|
parentAggregationLastL1RollingHashMessageNumber =
|
||||||
proofsToAggregate.parentAggregationLastL1RollingHashMessageNumber.toLong(),
|
proofsToAggregate.parentAggregationLastL1RollingHashMessageNumber.toLong(),
|
||||||
parentAggregationLastL1RollingHash = proofsToAggregate.parentAggregationLastL1RollingHash.encodeHex()
|
parentAggregationLastL1RollingHash = proofsToAggregate.parentAggregationLastL1RollingHash.encodeHex(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,15 +65,15 @@ data class AggregationProofRequestDto(
|
|||||||
|
|
||||||
internal class AggregationRequestDtoMapper(
|
internal class AggregationRequestDtoMapper(
|
||||||
private val executionProofResponseFileNameProvider: ProverFileNameProvider,
|
private val executionProofResponseFileNameProvider: ProverFileNameProvider,
|
||||||
private val compressionProofResponseFileNameProvider: ProverFileNameProvider
|
private val compressionProofResponseFileNameProvider: ProverFileNameProvider,
|
||||||
) : (ProofsToAggregate) -> SafeFuture<AggregationProofRequestDto> {
|
) : (ProofsToAggregate) -> SafeFuture<AggregationProofRequestDto> {
|
||||||
override fun invoke(proofsToAggregate: ProofsToAggregate): SafeFuture<AggregationProofRequestDto> {
|
override fun invoke(proofsToAggregate: ProofsToAggregate): SafeFuture<AggregationProofRequestDto> {
|
||||||
return SafeFuture.completedFuture(
|
return SafeFuture.completedFuture(
|
||||||
AggregationProofRequestDto.fromDomainObject(
|
AggregationProofRequestDto.fromDomainObject(
|
||||||
proofsToAggregate,
|
proofsToAggregate,
|
||||||
executionProofResponseFileNameProvider,
|
executionProofResponseFileNameProvider,
|
||||||
compressionProofResponseFileNameProvider
|
compressionProofResponseFileNameProvider,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,13 +95,13 @@ class FileBasedProofAggregationClientV2(
|
|||||||
hashFunction: HashFunction = Sha256HashFunction(),
|
hashFunction: HashFunction = Sha256HashFunction(),
|
||||||
executionProofResponseFileNameProvider: ProverFileNameProvider = ExecutionProofResponseFileNameProvider,
|
executionProofResponseFileNameProvider: ProverFileNameProvider = ExecutionProofResponseFileNameProvider,
|
||||||
compressionProofResponseFileNameProvider: ProverFileNameProvider = CompressionProofResponseFileNameProvider,
|
compressionProofResponseFileNameProvider: ProverFileNameProvider = CompressionProofResponseFileNameProvider,
|
||||||
jsonObjectMapper: ObjectMapper = JsonSerialization.proofResponseMapperV1
|
jsonObjectMapper: ObjectMapper = JsonSerialization.proofResponseMapperV1,
|
||||||
) :
|
) :
|
||||||
GenericFileBasedProverClient<
|
GenericFileBasedProverClient<
|
||||||
ProofsToAggregate,
|
ProofsToAggregate,
|
||||||
ProofToFinalize,
|
ProofToFinalize,
|
||||||
AggregationProofRequestDto,
|
AggregationProofRequestDto,
|
||||||
ProofToFinalizeJsonResponse
|
ProofToFinalizeJsonResponse,
|
||||||
>(
|
>(
|
||||||
config = config,
|
config = config,
|
||||||
vertx = vertx,
|
vertx = vertx,
|
||||||
@@ -109,18 +109,18 @@ class FileBasedProofAggregationClientV2(
|
|||||||
fileReader = FileReader(
|
fileReader = FileReader(
|
||||||
vertx,
|
vertx,
|
||||||
jsonObjectMapper,
|
jsonObjectMapper,
|
||||||
ProofToFinalizeJsonResponse::class.java
|
ProofToFinalizeJsonResponse::class.java,
|
||||||
),
|
),
|
||||||
requestFileNameProvider = AggregationProofFileNameProvider,
|
requestFileNameProvider = AggregationProofFileNameProvider,
|
||||||
responseFileNameProvider = AggregationProofFileNameProvider,
|
responseFileNameProvider = AggregationProofFileNameProvider,
|
||||||
proofIndexProvider = createProofIndexProviderFn(hashFunction),
|
proofIndexProvider = createProofIndexProviderFn(hashFunction),
|
||||||
requestMapper = AggregationRequestDtoMapper(
|
requestMapper = AggregationRequestDtoMapper(
|
||||||
executionProofResponseFileNameProvider = executionProofResponseFileNameProvider,
|
executionProofResponseFileNameProvider = executionProofResponseFileNameProvider,
|
||||||
compressionProofResponseFileNameProvider = compressionProofResponseFileNameProvider
|
compressionProofResponseFileNameProvider = compressionProofResponseFileNameProvider,
|
||||||
),
|
),
|
||||||
responseMapper = ProofToFinalizeJsonResponse::toDomainObject,
|
responseMapper = ProofToFinalizeJsonResponse::toDomainObject,
|
||||||
proofTypeLabel = "aggregation",
|
proofTypeLabel = "aggregation",
|
||||||
log = LogManager.getLogger(this::class.java)
|
log = LogManager.getLogger(this::class.java),
|
||||||
),
|
),
|
||||||
ProofAggregationProverClientV2 {
|
ProofAggregationProverClientV2 {
|
||||||
|
|
||||||
@@ -128,20 +128,20 @@ class FileBasedProofAggregationClientV2(
|
|||||||
fun createProofIndexProviderFn(
|
fun createProofIndexProviderFn(
|
||||||
hashFunction: HashFunction,
|
hashFunction: HashFunction,
|
||||||
executionProofResponseFileNameProvider: ProverFileNameProvider = ExecutionProofResponseFileNameProvider,
|
executionProofResponseFileNameProvider: ProverFileNameProvider = ExecutionProofResponseFileNameProvider,
|
||||||
compressionProofResponseFileNameProvider: ProverFileNameProvider = CompressionProofResponseFileNameProvider
|
compressionProofResponseFileNameProvider: ProverFileNameProvider = CompressionProofResponseFileNameProvider,
|
||||||
): (ProofsToAggregate) -> ProofIndex {
|
): (ProofsToAggregate) -> ProofIndex {
|
||||||
return { request: ProofsToAggregate ->
|
return { request: ProofsToAggregate ->
|
||||||
|
|
||||||
val requestDto = AggregationProofRequestDto.fromDomainObject(
|
val requestDto = AggregationProofRequestDto.fromDomainObject(
|
||||||
proofsToAggregate = request,
|
proofsToAggregate = request,
|
||||||
executionProofResponseFileNameProvider = executionProofResponseFileNameProvider,
|
executionProofResponseFileNameProvider = executionProofResponseFileNameProvider,
|
||||||
compressionProofResponseFileNameProvider = compressionProofResponseFileNameProvider
|
compressionProofResponseFileNameProvider = compressionProofResponseFileNameProvider,
|
||||||
)
|
)
|
||||||
val hash = hashRequest(hashFunction, requestDto)
|
val hash = hashRequest(hashFunction, requestDto)
|
||||||
ProofIndex(
|
ProofIndex(
|
||||||
startBlockNumber = request.startBlockNumber,
|
startBlockNumber = request.startBlockNumber,
|
||||||
endBlockNumber = request.endBlockNumber,
|
endBlockNumber = request.endBlockNumber,
|
||||||
hash = hash
|
hash = hash,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,13 +28,13 @@ open class GenericFileBasedProverClient<Request, Response, RequestDto, ResponseD
|
|||||||
private val responseFileNameProvider: ProverFileNameProvider,
|
private val responseFileNameProvider: ProverFileNameProvider,
|
||||||
private val fileMonitor: FileMonitor = FileMonitor(
|
private val fileMonitor: FileMonitor = FileMonitor(
|
||||||
vertx,
|
vertx,
|
||||||
FileMonitor.Config(config.pollingInterval, config.pollingTimeout)
|
FileMonitor.Config(config.pollingInterval, config.pollingTimeout),
|
||||||
),
|
),
|
||||||
private val proofIndexProvider: (Request) -> ProofIndex = ::blockIntervalProofIndex,
|
private val proofIndexProvider: (Request) -> ProofIndex = ::blockIntervalProofIndex,
|
||||||
private val requestMapper: (Request) -> SafeFuture<RequestDto>,
|
private val requestMapper: (Request) -> SafeFuture<RequestDto>,
|
||||||
private val responseMapper: (ResponseDto) -> Response,
|
private val responseMapper: (ResponseDto) -> Response,
|
||||||
private val proofTypeLabel: String,
|
private val proofTypeLabel: String,
|
||||||
private val log: Logger = LogManager.getLogger(GenericFileBasedProverClient::class.java)
|
private val log: Logger = LogManager.getLogger(GenericFileBasedProverClient::class.java),
|
||||||
) : Supplier<Number>
|
) : Supplier<Number>
|
||||||
where Request : BlockInterval,
|
where Request : BlockInterval,
|
||||||
Response : Any,
|
Response : Any,
|
||||||
@@ -62,7 +62,7 @@ open class GenericFileBasedProverClient<Request, Response, RequestDto, ResponseD
|
|||||||
"request already proven: {}={} reusedResponse={}",
|
"request already proven: {}={} reusedResponse={}",
|
||||||
proofTypeLabel,
|
proofTypeLabel,
|
||||||
proofIndex.intervalString(),
|
proofIndex.intervalString(),
|
||||||
responseFilePath
|
responseFilePath,
|
||||||
)
|
)
|
||||||
SafeFuture.completedFuture(responseFilePath)
|
SafeFuture.completedFuture(responseFilePath)
|
||||||
} else {
|
} else {
|
||||||
@@ -74,7 +74,7 @@ open class GenericFileBasedProverClient<Request, Response, RequestDto, ResponseD
|
|||||||
"request already in file system: {}={} reusedRequest={}",
|
"request already in file system: {}={} reusedRequest={}",
|
||||||
proofTypeLabel,
|
proofTypeLabel,
|
||||||
proofIndex.intervalString(),
|
proofIndex.intervalString(),
|
||||||
requestFileFound
|
requestFileFound,
|
||||||
)
|
)
|
||||||
SafeFuture.completedFuture(Unit)
|
SafeFuture.completedFuture(Unit)
|
||||||
} else {
|
} else {
|
||||||
@@ -83,7 +83,7 @@ open class GenericFileBasedProverClient<Request, Response, RequestDto, ResponseD
|
|||||||
fileWriter.write(
|
fileWriter.write(
|
||||||
proofRequestDto,
|
proofRequestDto,
|
||||||
requestFilePath,
|
requestFilePath,
|
||||||
config.inprogressRequestWritingSuffix
|
config.inprogressRequestWritingSuffix,
|
||||||
).thenApply {
|
).thenApply {
|
||||||
Unit
|
Unit
|
||||||
}
|
}
|
||||||
@@ -104,13 +104,13 @@ open class GenericFileBasedProverClient<Request, Response, RequestDto, ResponseD
|
|||||||
proofTypeLabel,
|
proofTypeLabel,
|
||||||
proofIndex.intervalString(),
|
proofIndex.intervalString(),
|
||||||
it.message,
|
it.message,
|
||||||
it
|
it,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun waitForResponse(
|
private fun waitForResponse(
|
||||||
responseFilePath: Path
|
responseFilePath: Path,
|
||||||
): SafeFuture<Path> {
|
): SafeFuture<Path> {
|
||||||
return fileMonitor.monitor(responseFilePath).thenCompose {
|
return fileMonitor.monitor(responseFilePath).thenCompose {
|
||||||
if (it is Err) {
|
if (it is Err) {
|
||||||
@@ -130,17 +130,17 @@ open class GenericFileBasedProverClient<Request, Response, RequestDto, ResponseD
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun findRequestFileIfAlreadyInFileSystem(
|
private fun findRequestFileIfAlreadyInFileSystem(
|
||||||
requestFileName: String
|
requestFileName: String,
|
||||||
): SafeFuture<String?> {
|
): SafeFuture<String?> {
|
||||||
return fileMonitor.findFile(
|
return fileMonitor.findFile(
|
||||||
directory = config.requestsDirectory,
|
directory = config.requestsDirectory,
|
||||||
pattern = inProgressFilePattern(requestFileName, config.inprogressProvingSuffixPattern)
|
pattern = inProgressFilePattern(requestFileName, config.inprogressProvingSuffixPattern),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun parseResponse(
|
protected open fun parseResponse(
|
||||||
responseFilePath: Path,
|
responseFilePath: Path,
|
||||||
proofIndex: ProofIndex
|
proofIndex: ProofIndex,
|
||||||
): SafeFuture<Response> {
|
): SafeFuture<Response> {
|
||||||
return fileReader.read(responseFilePath)
|
return fileReader.read(responseFilePath)
|
||||||
.thenCompose { result ->
|
.thenCompose { result ->
|
||||||
@@ -152,7 +152,7 @@ open class GenericFileBasedProverClient<Request, Response, RequestDto, ResponseD
|
|||||||
log.error(
|
log.error(
|
||||||
"Failed to read response file={} errorMessage={}",
|
"Failed to read response file={} errorMessage={}",
|
||||||
responseFilePath,
|
responseFilePath,
|
||||||
errorResponse.message
|
errorResponse.message,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,13 +165,13 @@ open class GenericFileBasedProverClient<Request, Response, RequestDto, ResponseD
|
|||||||
fun <R : BlockInterval> blockIntervalProofIndex(request: R): ProofIndex {
|
fun <R : BlockInterval> blockIntervalProofIndex(request: R): ProofIndex {
|
||||||
return ProofIndex(
|
return ProofIndex(
|
||||||
startBlockNumber = request.startBlockNumber,
|
startBlockNumber = request.startBlockNumber,
|
||||||
endBlockNumber = request.endBlockNumber
|
endBlockNumber = request.endBlockNumber,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createDirectoryIfNotExists(
|
fun createDirectoryIfNotExists(
|
||||||
directory: Path,
|
directory: Path,
|
||||||
log: Logger = LogManager.getLogger(GenericFileBasedProverClient::class.java)
|
log: Logger = LogManager.getLogger(GenericFileBasedProverClient::class.java),
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
if (directory.notExists()) {
|
if (directory.notExists()) {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user