Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blob Decompressor and Some Helpers #230

Merged
merged 10 commits into from
Oct 23, 2024
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package build.linea

import java.net.URI

fun URI.getPortWithSchemaDefaults(): Int {
return if (port != -1) {
port
} else {
when (scheme.lowercase()) {
"http" -> 80
"https" -> 443
// Focous on HTTP as it what we need for now
else -> throw IllegalArgumentException("Unsupported scheme: $scheme")
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package net.consensys.jvm
package build.linea.jvm

import java.io.File
import java.nio.file.Files
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package build.linea

import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.jupiter.api.Test
import java.net.URI

class URIExtensionsTest {
@Test
fun `getPortWithSchemaDefaults`() {
assertThat(URI.create("http://example.com").getPortWithSchemaDefaults()).isEqualTo(80)
assertThat(URI.create("https://example.com").getPortWithSchemaDefaults()).isEqualTo(443)
assertThat(URI.create("http://example.com:8080").getPortWithSchemaDefaults()).isEqualTo(8080)
assertThat(URI.create("https://example.com:8080").getPortWithSchemaDefaults()).isEqualTo(8080)
assertThat(URI.create("myschema://example.com:8080").getPortWithSchemaDefaults()).isEqualTo(8080)
assertThatThrownBy { (URI.create("mySchema://example.com").getPortWithSchemaDefaults()) }
.isInstanceOf(IllegalArgumentException::class.java)
.hasMessage("Unsupported scheme: mySchema")
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package net.consensys.jvm
package build.linea.jvm

import net.consensys.jvm.ResourcesUtil.copyResourceToTmpDir
import build.linea.jvm.ResourcesUtil.copyResourceToTmpDir
import org.assertj.core.api.AssertionsForClassTypes.assertThat
import org.junit.jupiter.api.Test
import java.nio.file.Files
Expand Down
9 changes: 9 additions & 0 deletions jvm-libs/generic/extensions/tuweni/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
plugins {
id 'net.consensys.zkevm.kotlin-library-conventions'
}

dependencies {
api "io.tmio:tuweni-bytes:${libs.versions.tuweni.get()}"
implementation(project(':jvm-libs:generic:extensions:kotlin'))
testImplementation "io.tmio:tuweni-units:${libs.versions.tuweni.get()}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package build.linea.tuweni

import net.consensys.toULong
import org.apache.tuweni.bytes.Bytes32
import java.math.BigInteger

fun ByteArray.toBytes32(): Bytes32 = Bytes32.wrap(this)
fun ByteArray.sliceAsBytes32(sliceIndex: Int): Bytes32 = Bytes32.wrap(this, /*offset*/sliceIndex * 32)
fun Bytes32.toULong(): ULong = BigInteger(this.toArray()).toULong()
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package build.linea.tuweni

import net.consensys.toBigInteger
import org.apache.tuweni.bytes.Bytes32
import org.apache.tuweni.units.bigints.UInt256
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import kotlin.random.Random

class Bytes32Test {
@BeforeEach
fun setUp() {
// workaround: need this to load the functions otherwise JUNit gets stuck ¯\_(ツ)_/¯
Random.Default.nextBytes(32).sliceAsBytes32(0)
UInt256.ZERO.toBytes().toULong()
}

@Test
fun testSliceAsBytes32() {
val bytes = Random.Default.nextBytes(3 * 32 - 1)
assertThat(bytes.sliceAsBytes32(0)).isEqualTo(Bytes32.wrap(bytes, 0))
assertThat(bytes.sliceAsBytes32(1)).isEqualTo(Bytes32.wrap(bytes, 32))
assertThatThrownBy { bytes.sliceAsBytes32(2) }
.isInstanceOf(IllegalArgumentException::class.java)
}

@Test
fun testToULong() {
UInt256.ZERO.toBytes()
.also { bytes -> assertThat(bytes.toULong()).isEqualTo(0uL) }
UInt256.valueOf(Long.MAX_VALUE)
.also { bytes -> assertThat(bytes.toULong()).isEqualTo(Long.MAX_VALUE.toULong()) }
UInt256.valueOf(Long.MAX_VALUE).add(UInt256.ONE)
.also { bytes -> assertThat(bytes.toULong()).isEqualTo(Long.MAX_VALUE.toULong() + 1UL) }
UInt256.valueOf(ULong.MAX_VALUE.toBigInteger())
.also { bytes -> assertThat(bytes.toULong()).isEqualTo(ULong.MAX_VALUE) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,6 @@ class VertxHttpJsonRpcClientFactory(
}

fun createV2(
vertx: Vertx,
endpoints: Set<URL>,
maxInflightRequestsPerClient: UInt? = null,
retryConfig: RequestRetryConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ class JsonRpcV2ClientImplTest {
)

private fun createClientAndSetupWireMockServer(
vertx: Vertx,
responseObjectMapper: ObjectMapper = defaultObjectMapper,
requestObjectMapper: ObjectMapper = defaultObjectMapper,
retryConfig: RequestRetryConfig = defaultRetryConfig,
Expand All @@ -89,7 +88,6 @@ class JsonRpcV2ClientImplTest {
endpoint = URI(wiremock.baseUrl() + path).toURL()

return factory.createV2(
vertx = vertx,
endpoints = setOf(endpoint),
retryConfig = retryConfig,
requestObjectMapper = requestObjectMapper,
Expand All @@ -103,7 +101,7 @@ class JsonRpcV2ClientImplTest {
this.vertx = vertx
this.meterRegistry = SimpleMeterRegistry()
this.factory = VertxHttpJsonRpcClientFactory(vertx, meterRegistry)
this.client = createClientAndSetupWireMockServer(vertx)
this.client = createClientAndSetupWireMockServer()
}

@AfterEach
Expand Down Expand Up @@ -192,7 +190,7 @@ class JsonRpcV2ClientImplTest {
fun `request params shall use defined objectMapper and not affect json-rpc envelope`() {
val obj = User(name = "John", email = "email@example.com", address = "0x01ffbb".decodeHex(), value = 987UL)

createClientAndSetupWireMockServer(vertx, requestObjectMapper = defaultObjectMapper).also { client ->
createClientAndSetupWireMockServer(requestObjectMapper = defaultObjectMapper).also { client ->
replyRequestWith(200, jsonRpcResultOk)
client.makeRequest(
method = "someMethod",
Expand Down Expand Up @@ -223,7 +221,7 @@ class JsonRpcV2ClientImplTest {
}
)

createClientAndSetupWireMockServer(vertx, requestObjectMapper = objMapperWithNumbersAsHex).also { client ->
createClientAndSetupWireMockServer(requestObjectMapper = objMapperWithNumbersAsHex).also { client ->
replyRequestWith(200, jsonRpcResultOk)
client.makeRequest(
method = "someMethod",
Expand Down Expand Up @@ -456,7 +454,6 @@ class JsonRpcV2ClientImplTest {
@Test
fun `when it gets an error propagates to shallRetryRequestPredicate and retries while is true`() {
createClientAndSetupWireMockServer(
vertx,
retryConfig = retryConfig(maxRetries = 10u)
).also { client ->
val responses = listOf(
Expand Down Expand Up @@ -507,7 +504,6 @@ class JsonRpcV2ClientImplTest {
@Test
fun `when it has connection error propagates to shallRetryRequestPredicate and retries while is true`() {
createClientAndSetupWireMockServer(
vertx,
retryConfig = retryConfig(maxRetries = 10u)
).also { client ->
// stop the server to simulate connection error
Expand Down Expand Up @@ -543,7 +539,6 @@ class JsonRpcV2ClientImplTest {
@Test
fun `when it has connection error propagates to shallRetryRequestPredicate and retries until retry config elapses`() {
createClientAndSetupWireMockServer(
vertx,
retryConfig = retryConfig(maxRetries = 2u, timeout = 8.seconds, backoffDelay = 5.milliseconds)
).also { client ->
// stop the server to simulate connection error
Expand Down Expand Up @@ -580,7 +575,6 @@ class JsonRpcV2ClientImplTest {
(it.value as String).startsWith("retry_a")
}
createClientAndSetupWireMockServer(
vertx,
retryConfig = RequestRetryConfig(
maxRetries = 10u,
timeout = 5.minutes,
Expand Down
1 change: 1 addition & 0 deletions jvm-libs/generic/vertx-helper/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ plugins {
}

dependencies {
implementation project(':jvm-libs:generic:extensions:kotlin')
implementation project(':jvm-libs:generic:extensions:futures')
implementation "io.vertx:vertx-core"
implementation "io.vertx:vertx-web"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package net.consensys.linea.vertx

import build.linea.getPortWithSchemaDefaults
import io.vertx.core.http.HttpClientOptions
import java.net.URI

fun <T : HttpClientOptions> T.setDefaultsFrom(uri: URI): T {
isSsl = uri.scheme.lowercase() == "https"
defaultHost = uri.host
defaultPort = uri.getPortWithSchemaDefaults()

return this
}
2 changes: 1 addition & 1 deletion jvm-libs/linea/blob-compressor/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ apply from: rootProject.file("gradle/publishing.gradle")

dependencies {
implementation "net.java.dev.jna:jna:${libs.versions.jna.get()}"
testImplementation project(":jvm-libs:generic:extensions:kotlin")
implementation project(":jvm-libs:generic:extensions:kotlin")
testImplementation project(":jvm-libs:linea:blob-shnarf-calculator")
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package net.consensys.linea.blob

import build.linea.jvm.ResourcesUtil.copyResourceToTmpDir
import com.sun.jna.Library
import com.sun.jna.Native
import net.consensys.jvm.ResourcesUtil.copyResourceToTmpDir

interface GoNativeBlobCompressor {
jonesho marked this conversation as resolved.
Show resolved Hide resolved

Expand Down
Binary file not shown.
59 changes: 59 additions & 0 deletions jvm-libs/linea/blob-decompressor/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
plugins {
id 'net.consensys.zkevm.kotlin-library-conventions'
id 'net.consensys.zkevm.linea-native-libs-helper'
alias(libs.plugins.jreleaser)
id 'java-test-fixtures'
}

description = 'Java JNA wrapper for Linea Blob Decompressor Library implemented in GO Lang'
apply from: rootProject.file("gradle/publishing.gradle")

dependencies {
implementation "net.java.dev.jna:jna:${libs.versions.jna.get()}"
implementation project(":jvm-libs:generic:extensions:kotlin")

testImplementation project(":jvm-libs:linea:blob-compressor")
testImplementation(testFixtures(project(":jvm-libs:linea:blob-compressor")))
testImplementation(project(":jvm-libs:linea:testing:file-system"))
testImplementation("io.tmio:tuweni-bytes:${libs.versions.tuweni.get()}")
testImplementation("org.hyperledger.besu:besu-datatypes:${libs.versions.besu.get()}")
testImplementation "org.hyperledger.besu:evm:${libs.versions.besu.get()}"
testImplementation("org.hyperledger.besu.internal:core:${libs.versions.besu.get()}")
testImplementation("org.hyperledger.besu:plugin-api:${libs.versions.besu.get()}")
testImplementation("org.hyperledger.besu.internal:rlp:${libs.versions.besu.get()}")
}

jar {
dependsOn configurations.runtimeClasspath
}

test {
// we cannot have more 1 compressor per JVM, hence we disable parallel execution
// because multiple threads would cause issues with the native library
systemProperties["junit.jupiter.execution.parallel.enabled"] = false
maxParallelForks = 1
}

def libsZipDownloadOutputDir = project.parent.layout.buildDirectory.asFile.get().absolutePath

task downloadNativeLibs {
doLast {
fetchLibFromZip("https://github.com/Consensys/linea-monorepo/releases/download/blob-libs-v1.1.0-test8/linea-blob-libs-v1.1.0-test8.zip", "blob_decompressor", libsZipDownloadOutputDir)
}
}

compileKotlin {
dependsOn tasks.downloadNativeLibs
}

task cleanResources(type: Delete) {
fileTree(project.layout.projectDirectory.dir('src/main/resources'))
.filter {
it.name.endsWith(".so") || it.name.endsWith(".dll") || it.name.endsWith(".dylib")
}.each {
println("Deleting: ${it}")
jpnovais marked this conversation as resolved.
Show resolved Hide resolved
delete it
}
}

clean.dependsOn cleanResources
Loading
Loading