Skip to content

Commit 79da1a1

Browse files
authored
[Coordinator] Add client for linea_generateVirtualBlockConflatedTracesToFileV1 (#2423)
1 parent ffd5fcd commit 79da1a1

File tree

3 files changed

+224
-2
lines changed

3 files changed

+224
-2
lines changed

coordinator/clients/traces-generator-api-client/src/main/kotlin/net/consensys/zkevm/coordinator/clients/TracesClientResponsesParser.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,8 @@ object TracesClientResponsesParser {
112112
result.getString("tracesEngineVersion"),
113113
)
114114
}
115+
116+
internal fun parseVirtualBlockConflatedTracesToFileResponse(
117+
jsonRpcResponse: JsonRpcSuccessResponse,
118+
): GenerateTracesResponse = parseConflatedTracesToFileResponse(jsonRpcResponse)
115119
}

coordinator/clients/traces-generator-api-client/src/main/kotlin/net/consensys/zkevm/coordinator/clients/TracesGeneratorJsonRpcClientV2.kt

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.github.michaelbull.result.mapEither
66
import io.vertx.core.Vertx
77
import io.vertx.core.json.JsonObject
88
import io.vertx.kotlin.core.json.get
9+
import linea.kotlin.encodeHex
910
import net.consensys.linea.async.toSafeFuture
1011
import net.consensys.linea.errors.ErrorResponse
1112
import net.consensys.linea.jsonrpc.JsonRpcRequest
@@ -28,7 +29,7 @@ class TracesGeneratorJsonRpcClientV2(
2829
private val rpcClient: JsonRpcClient,
2930
private val config: Config,
3031
) :
31-
TracesCountersClientV2, TracesConflationClientV2 {
32+
TracesCountersClientV2, TracesConflationClientV2, TracesConflationVirtualBlockClientV1 {
3233
constructor(
3334
vertx: Vertx,
3435
rpcClient: JsonRpcClient,
@@ -88,6 +89,21 @@ class TracesGeneratorJsonRpcClientV2(
8889
) { createFallbackConflatedTracesResponse(startBlockNumber, endBlockNumber) }
8990
}
9091

92+
override fun generateVirtualBlockConflatedTracesToFile(
93+
blockNumber: ULong,
94+
transaction: ByteArray,
95+
): SafeFuture<Result<GenerateTracesResponse, ErrorResponse<TracesServiceErrorType>>> {
96+
val jsonRequest =
97+
requestBuilder.buildGenerateVirtualBlockConflatedTracesToFileV1Request(
98+
blockNumber = blockNumber,
99+
transaction = transaction,
100+
)
101+
return executeWithFallback(
102+
jsonRequest,
103+
TracesClientResponsesParser::parseVirtualBlockConflatedTracesToFileResponse,
104+
) { createFallbackVirtualBlockConflatedTracesResponse(blockNumber) }
105+
}
106+
91107
private fun createFallbackTracesCountersResponse(): GetTracesCountersResponse {
92108
return GetTracesCountersResponse(
93109
tracesCounters = config.fallBackTracesCounters,
@@ -106,6 +122,16 @@ class TracesGeneratorJsonRpcClientV2(
106122
)
107123
}
108124

125+
private fun createFallbackVirtualBlockConflatedTracesResponse(
126+
blockNumber: ULong,
127+
): GenerateTracesResponse {
128+
val defaultFileName = "$blockNumber.fake-empty.conflated.${config.expectedTracesApiVersion}.lt"
129+
return GenerateTracesResponse(
130+
tracesFileName = defaultFileName,
131+
tracesEngineVersion = config.expectedTracesApiVersion,
132+
)
133+
}
134+
109135
private fun <T> executeWithFallback(
110136
jsonRequest: JsonRpcRequest,
111137
responseParser: (JsonRpcSuccessResponse) -> T,
@@ -178,10 +204,33 @@ class TracesGeneratorJsonRpcClientV2(
178204
),
179205
)
180206
}
207+
208+
fun buildGenerateVirtualBlockConflatedTracesToFileV1Request(
209+
blockNumber: ULong,
210+
transaction: ByteArray,
211+
): JsonRpcRequest {
212+
return JsonRpcRequestListParams(
213+
"2.0",
214+
id.incrementAndGet(),
215+
"linea_generateVirtualBlockConflatedTracesToFileV1",
216+
listOf(
217+
JsonObject.of(
218+
"blockNumber",
219+
blockNumber,
220+
"txsRlpEncoded",
221+
listOf(transaction.encodeHex()),
222+
),
223+
),
224+
)
225+
}
181226
}
182227

183228
companion object {
184-
internal val retryableMethods = setOf("linea_getBlockTracesCountersV2", "linea_generateConflatedTracesToFileV2")
229+
internal val retryableMethods = setOf(
230+
"linea_getBlockTracesCountersV2",
231+
"linea_generateConflatedTracesToFileV2",
232+
"linea_generateVirtualBlockConflatedTracesToFileV1",
233+
)
185234

186235
@Suppress("UNCHECKED_CAST")
187236
val requestPriorityComparator =

coordinator/clients/traces-generator-api-client/src/test/kotlin/net/consensys/zkevm/coordinator/clients/TracesGeneratorJsonRpcClientV2Test.kt

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import io.micrometer.core.instrument.simple.SimpleMeterRegistry
1717
import io.vertx.core.Vertx
1818
import io.vertx.core.json.JsonObject
1919
import io.vertx.junit5.VertxExtension
20+
import linea.kotlin.encodeHex
2021
import net.consensys.linea.async.get
2122
import net.consensys.linea.errors.ErrorResponse
2223
import net.consensys.linea.jsonrpc.client.JsonRpcClient
@@ -500,4 +501,172 @@ class TracesGeneratorJsonRpcClientV2Test {
500501
assertThat(result.value.tracesCounters).isEqualTo(TracesCountersV2.EMPTY_TRACES_COUNT)
501502
assertThat(result.value.tracesEngineVersion).isEqualTo(expectedTracesApiVersion)
502503
}
504+
505+
@Test
506+
fun generateVirtualBlockConflatedTracesToFile() {
507+
val blockNumber = 50L
508+
509+
val tracesEngineVersion = "0.0.1"
510+
val conflatedTracesFileName =
511+
"$blockNumber.conflated.v$tracesEngineVersion.json.gz"
512+
513+
val response =
514+
JsonObject.of(
515+
"jsonrpc",
516+
"2.0",
517+
"id",
518+
1,
519+
"result",
520+
mapOf(
521+
"tracesEngineVersion" to tracesEngineVersion,
522+
"conflatedTracesFileName" to conflatedTracesFileName,
523+
),
524+
)
525+
526+
wiremock.stubFor(
527+
post("/")
528+
.withHeader("Content-Type", containing("application/json"))
529+
.willReturn(
530+
ok()
531+
.withHeader("Content-type", "application/json")
532+
.withBody(response.toString().toByteArray()),
533+
),
534+
)
535+
536+
val queryBlockNumber = 50UL
537+
val queryTxn = Random.nextBytes(32)
538+
539+
val resultFuture =
540+
tracesGeneratorClient.generateVirtualBlockConflatedTracesToFile(
541+
queryBlockNumber,
542+
queryTxn,
543+
)
544+
resultFuture.get()
545+
546+
assertThat(resultFuture)
547+
.isCompletedWithValue(
548+
Ok(GenerateTracesResponse(conflatedTracesFileName, tracesEngineVersion)),
549+
)
550+
551+
val expectedJsonRequest =
552+
JsonObject.of(
553+
"jsonrpc",
554+
"2.0",
555+
"id",
556+
1,
557+
"method",
558+
"linea_generateVirtualBlockConflatedTracesToFileV1",
559+
"params",
560+
listOf(
561+
JsonObject.of(
562+
"blockNumber",
563+
queryBlockNumber.toLong(),
564+
"txsRlpEncoded",
565+
listOf(queryTxn.encodeHex()),
566+
),
567+
),
568+
)
569+
wiremock.verify(
570+
postRequestedFor(urlEqualTo("/"))
571+
.withHeader("Content-Type", equalTo("application/json"))
572+
.withRequestBody(equalToJson(expectedJsonRequest.toString(), false, true)),
573+
)
574+
}
575+
576+
@Test
577+
fun error_generateVirtualConflatedTracesToFile() {
578+
val errorMessage = "Internal error!"
579+
val data = "BLOCK_MISSING_IN_CHAIN: Block 1 doesn't exist in the chain"
580+
val response = jsonRpcErrorResponse(errorMessage, data)
581+
582+
wiremock.stubFor(
583+
post("/")
584+
.withHeader("Content-Type", containing("application/json"))
585+
.willReturn(
586+
ok()
587+
.withHeader("Content-type", "application/json")
588+
.withBody(response.toString().toByteArray()),
589+
),
590+
)
591+
592+
val queryBlockNumber = 1UL
593+
val queryTxn = Random.nextBytes(32)
594+
val resultFuture =
595+
tracesGeneratorClient.generateVirtualBlockConflatedTracesToFile(
596+
queryBlockNumber,
597+
queryTxn,
598+
)
599+
resultFuture.get()
600+
601+
assertThat(resultFuture)
602+
.isCompletedWithValue(
603+
Err(ErrorResponse(TracesServiceErrorType.BLOCK_MISSING_IN_CHAIN, errorMessage)),
604+
)
605+
}
606+
607+
@Test
608+
fun error_generateVirtualBlockConflatedTracesToFile_retriesRequest() {
609+
val tracesEngineVersion = "0.0.1"
610+
val errorMessage = "Internal error!"
611+
val data = "BLOCK_MISSING_IN_CHAIN: Block 1 doesn't exist in the chain"
612+
val jsonRpcErrorResponse = jsonRpcErrorResponse(errorMessage, data)
613+
wiremock.stubFor(
614+
post("/")
615+
.inScenario("retry")
616+
.whenScenarioStateIs(STARTED)
617+
.willSetStateTo("first failure")
618+
.withHeader("Content-Type", containing("application/json"))
619+
.willReturn(
620+
aResponse()
621+
.withStatus(500)
622+
.withBody("Internal Server Error"),
623+
),
624+
)
625+
wiremock.stubFor(
626+
post("/")
627+
.inScenario("retry")
628+
.whenScenarioStateIs("first failure")
629+
.willSetStateTo("second failure")
630+
.withHeader("Content-Type", containing("application/json"))
631+
.willReturn(
632+
aResponse()
633+
.withStatus(200)
634+
.withBody(jsonRpcErrorResponse.toString()),
635+
),
636+
)
637+
wiremock.stubFor(
638+
post("/")
639+
.inScenario("retry")
640+
.whenScenarioStateIs("second failure")
641+
.willSetStateTo("success")
642+
.withHeader("Content-Type", containing("application/json"))
643+
.willReturn(
644+
ok()
645+
.withHeader("Content-type", "application/json")
646+
.withBody(
647+
JsonObject.of(
648+
"jsonrpc",
649+
"2.0",
650+
"id",
651+
1,
652+
"result",
653+
mapOf(
654+
"tracesEngineVersion" to tracesEngineVersion,
655+
"conflatedTracesFileName" to "conflated-traces-1.json",
656+
),
657+
).toString(),
658+
),
659+
),
660+
)
661+
662+
val queryBlockNumber = 1UL
663+
val queryTxn = Random.nextBytes(32)
664+
val resultFuture =
665+
tracesGeneratorClient.generateVirtualBlockConflatedTracesToFile(
666+
queryBlockNumber,
667+
queryTxn,
668+
)
669+
670+
assertThat(resultFuture.get()).isInstanceOf(Ok::class.java)
671+
}
503672
}

0 commit comments

Comments
 (0)