You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuweni.apache.org by to...@apache.org on 2022/06/11 08:43:17 UTC
[incubator-tuweni] branch main updated: separate stratum app from stratum server
This is an automated email from the ASF dual-hosted git repository.
toulmean pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-tuweni.git
The following commit(s) were added to refs/heads/main by this push:
new 1b166742 separate stratum app from stratum server
new fa6d9ef9 Merge pull request #413 from atoulme/strat
1b166742 is described below
commit 1b166742beffa5796986320871aa2dec55025152
Author: Antoine Toulme <an...@lunar-ocean.com>
AuthorDate: Fri Jun 10 23:24:44 2022 -0700
separate stratum app from stratum server
---
.../org/apache/tuweni/jsonrpc/JSONRPCClient.kt | 17 +++-
settings.gradle | 2 +
stratum/{server => client}/build.gradle | 9 +-
.../org/apache/tuweni/stratum/client}/JsonRpc.kt | 8 +-
.../org/apache/tuweni/stratum/client/PoW.kt} | 24 +----
stratum/client/src/main/resources/logback.xml | 27 +++++
stratum/{server => proxy}/build.gradle | 13 ++-
.../org/apache/tuweni/stratum/StratumServerApp.kt | 110 +++++++++++++++++++++
stratum/proxy/src/main/resources/logback.xml | 27 +++++
stratum/server/build.gradle | 2 +
.../org/apache/tuweni/stratum/server/JsonRpc.kt | 4 +-
.../tuweni/stratum/server/StratumProtocol.kt | 29 ++++--
.../apache/tuweni/stratum/server/StratumServer.kt | 21 +++-
.../tuweni/stratum/server/StratumProtocolTest.kt | 9 +-
14 files changed, 254 insertions(+), 48 deletions(-)
diff --git a/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/JSONRPCClient.kt b/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/JSONRPCClient.kt
index d2dbdf12..147bd8ca 100644
--- a/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/JSONRPCClient.kt
+++ b/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/JSONRPCClient.kt
@@ -22,7 +22,9 @@ import io.vertx.core.buffer.Buffer
import io.vertx.core.tracing.TracingPolicy
import io.vertx.ext.web.client.WebClient
import io.vertx.ext.web.client.WebClientOptions
+import io.vertx.kotlin.coroutines.dispatcher
import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Deferred
import org.apache.tuweni.eth.Address
import org.apache.tuweni.eth.JSONRPCRequest
@@ -32,6 +34,7 @@ import org.apache.tuweni.units.bigints.UInt256
import java.io.Closeable
import java.util.Base64
import java.util.concurrent.atomic.AtomicInteger
+import kotlin.coroutines.CoroutineContext
val mapper = ObjectMapper()
@@ -44,12 +47,18 @@ class JSONRPCClient(
val userAgent: String = "Apache Tuweni JSON-RPC Client",
val basicAuthenticationEnabled: Boolean = false,
val basicAuthenticationUsername: String = "",
- val basicAuthenticationPassword: String = ""
-) : Closeable {
+ val basicAuthenticationPassword: String = "",
+ override val coroutineContext: CoroutineContext = vertx.dispatcher(),
+) : Closeable, CoroutineScope {
val requestCounter = AtomicInteger(1)
- val client = WebClient.create(vertx, WebClientOptions().setUserAgent(userAgent).setTryUseCompression(true).setTracingPolicy(TracingPolicy.ALWAYS) as WebClientOptions)
- val authorizationHeader = "Basic " + Base64.getEncoder().encode((basicAuthenticationUsername + ":" + basicAuthenticationPassword).toByteArray())
+ val client = WebClient.create(
+ vertx,
+ WebClientOptions().setUserAgent(userAgent).setTryUseCompression(true)
+ .setTracingPolicy(TracingPolicy.ALWAYS) as WebClientOptions
+ )
+ val authorizationHeader = "Basic " + Base64.getEncoder()
+ .encode((basicAuthenticationUsername + ":" + basicAuthenticationPassword).toByteArray())
suspend fun sendRequest(request: JSONRPCRequest): Deferred<JSONRPCResponse> {
val deferred = CompletableDeferred<JSONRPCResponse>()
diff --git a/settings.gradle b/settings.gradle
index 38ac4ad9..19295831 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -61,7 +61,9 @@ include 'scuttlebutt-handshake'
include 'scuttlebutt-rpc'
include 'scuttlebutt-client-lib'
include 'ssz'
+include 'stratum:client'
include 'stratum:server'
+include 'stratum:proxy'
include 'toml'
include 'units'
include 'wallet'
diff --git a/stratum/server/build.gradle b/stratum/client/build.gradle
similarity index 87%
copy from stratum/server/build.gradle
copy to stratum/client/build.gradle
index a4f4ef48..4a40e3f4 100644
--- a/stratum/server/build.gradle
+++ b/stratum/client/build.gradle
@@ -10,11 +10,13 @@
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
-description = 'Implementation of a Stratum server'
+plugins { id 'application' }
+description = 'Implementation of a Stratum client'
dependencies {
implementation project(':bytes')
+ implementation project(':pow')
implementation project(':units')
implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation 'com.google.guava:guava'
@@ -33,3 +35,8 @@ dependencies {
runtimeOnly 'ch.qos.logback:logback-classic'
}
+
+application {
+ mainClassName = 'org.apache.tuweni.stratum.client.MainKt'
+ applicationName = 'stratum-client'
+}
diff --git a/stratum/server/src/main/kotlin/org/apache/tuweni/stratum/server/JsonRpc.kt b/stratum/client/src/main/kotlin/org/apache/tuweni/stratum/client/JsonRpc.kt
similarity index 88%
copy from stratum/server/src/main/kotlin/org/apache/tuweni/stratum/server/JsonRpc.kt
copy to stratum/client/src/main/kotlin/org/apache/tuweni/stratum/client/JsonRpc.kt
index 8b365453..4217ed9c 100644
--- a/stratum/server/src/main/kotlin/org/apache/tuweni/stratum/server/JsonRpc.kt
+++ b/stratum/client/src/main/kotlin/org/apache/tuweni/stratum/client/JsonRpc.kt
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.tuweni.stratum.server
+package org.apache.tuweni.stratum.client
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.annotation.JsonProperty
@@ -23,7 +23,7 @@ import org.apache.tuweni.bytes.Bytes32
@JsonIgnoreProperties(ignoreUnknown = true)
data class JsonRpcRequest(
- @JsonProperty("version") val version: String?,
+ @JsonProperty("jsonrpc") val version: String? = "2.0",
@JsonProperty("method") val method: String,
@JsonProperty("params") val params: MutableList<Any> = mutableListOf(),
@JsonProperty("id") val id: String
@@ -36,6 +36,6 @@ data class JsonRpcRequest(
data class JsonRpcSuccessResponse(
@JsonProperty("id") val id: String,
- @JsonProperty("version") val version: String = "2.0",
- @JsonProperty("result") val result: Any
+ @JsonProperty("result") val result: Any,
+ @JsonProperty("error") val error: Any?
)
diff --git a/stratum/server/src/main/kotlin/org/apache/tuweni/stratum/server/JsonRpc.kt b/stratum/client/src/main/kotlin/org/apache/tuweni/stratum/client/PoW.kt
similarity index 53%
copy from stratum/server/src/main/kotlin/org/apache/tuweni/stratum/server/JsonRpc.kt
copy to stratum/client/src/main/kotlin/org/apache/tuweni/stratum/client/PoW.kt
index 8b365453..4e4146db 100644
--- a/stratum/server/src/main/kotlin/org/apache/tuweni/stratum/server/JsonRpc.kt
+++ b/stratum/client/src/main/kotlin/org/apache/tuweni/stratum/client/PoW.kt
@@ -14,28 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.tuweni.stratum.server
+package org.apache.tuweni.stratum.client
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties
-import com.fasterxml.jackson.annotation.JsonProperty
import org.apache.tuweni.bytes.Bytes
import org.apache.tuweni.bytes.Bytes32
+import org.apache.tuweni.units.bigints.UInt256
-@JsonIgnoreProperties(ignoreUnknown = true)
-data class JsonRpcRequest(
- @JsonProperty("version") val version: String?,
- @JsonProperty("method") val method: String,
- @JsonProperty("params") val params: MutableList<Any> = mutableListOf(),
- @JsonProperty("id") val id: String
-) {
+data class PoWInput(val target: UInt256, val prePowHash: Bytes, val blockNumber: Long)
- fun bytes32(i: Int): Bytes32 = Bytes32.fromHexString(params[i] as String)
-
- fun bytes(i: Int): Bytes = Bytes.fromHexString(params[i] as String)
-}
-
-data class JsonRpcSuccessResponse(
- @JsonProperty("id") val id: String,
- @JsonProperty("version") val version: String = "2.0",
- @JsonProperty("result") val result: Any
-)
+data class PoWSolution(val nonce: Long, val mixHash: Bytes32, val solution: Bytes?, val powHash: Bytes)
diff --git a/stratum/client/src/main/resources/logback.xml b/stratum/client/src/main/resources/logback.xml
new file mode 100644
index 00000000..6c9cb319
--- /dev/null
+++ b/stratum/client/src/main/resources/logback.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
+ file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
+ to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations under the License.
+-->
+<configuration scan="true">
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <!-- encoders are assigned the type
+ ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/stratum/server/build.gradle b/stratum/proxy/build.gradle
similarity index 82%
copy from stratum/server/build.gradle
copy to stratum/proxy/build.gradle
index a4f4ef48..3227d2ad 100644
--- a/stratum/server/build.gradle
+++ b/stratum/proxy/build.gradle
@@ -10,12 +10,18 @@
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
-description = 'Implementation of a Stratum server'
+
+plugins { id 'application' }
+
+description = 'Stratum proxy for getWork/submitWork'
dependencies {
implementation project(':bytes')
+ implementation project(':jsonrpc')
implementation project(':units')
+ implementation project(':eth')
+ implementation project(':stratum:server')
implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation 'com.google.guava:guava'
implementation 'io.vertx:vertx-core'
@@ -33,3 +39,8 @@ dependencies {
runtimeOnly 'ch.qos.logback:logback-classic'
}
+
+application {
+ mainClassName = 'org.apache.tuweni.stratum.StratumServerAppKt'
+ applicationName = 'stratum-proxy'
+}
diff --git a/stratum/proxy/src/main/kotlin/org/apache/tuweni/stratum/StratumServerApp.kt b/stratum/proxy/src/main/kotlin/org/apache/tuweni/stratum/StratumServerApp.kt
new file mode 100644
index 00000000..8a548e5b
--- /dev/null
+++ b/stratum/proxy/src/main/kotlin/org/apache/tuweni/stratum/StratumServerApp.kt
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuweni.stratum
+
+import io.vertx.core.Vertx
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withContext
+import org.apache.tuweni.bytes.Bytes
+import org.apache.tuweni.bytes.Bytes32
+import org.apache.tuweni.eth.JSONRPCRequest
+import org.apache.tuweni.jsonrpc.JSONRPCClient
+import org.apache.tuweni.stratum.server.PoWInput
+import org.apache.tuweni.stratum.server.StratumServer
+import org.apache.tuweni.units.bigints.UInt256
+import org.slf4j.LoggerFactory
+import java.util.concurrent.atomic.AtomicInteger
+import java.util.concurrent.atomic.AtomicReference
+import kotlin.system.exitProcess
+
+val logger = LoggerFactory.getLogger("stratum")
+
+fun main(args: Array<String>) {
+ if (args.size < 1) {
+ println("[USAGE] port")
+ exitProcess(1)
+ }
+ val vertx = Vertx.vertx()
+ val client = JSONRPCClient(vertx, "http://localhost:8545", "")
+
+ val port = args[0].toInt()
+ val idCounter = AtomicInteger(0)
+ val seedReference = AtomicReference<Bytes32>()
+ val server = StratumServer(
+ vertx, port = port, networkInterface = "0.0.0.0",
+ submitCallback = { solution ->
+ logger.info("Got solution $solution")
+ withContext(client.coroutineContext) {
+ val req = JSONRPCRequest(
+ id = idCounter.incrementAndGet(),
+ method = "eth_submitWork",
+ params = arrayOf(
+ Bytes.ofUnsignedLong(solution.nonce).toHexString(),
+ solution.powHash.toHexString(),
+ solution.mixHash.toHexString()
+ )
+ )
+ logger.info("Sending work back to client $req")
+ val response = client.sendRequest(req)
+
+ val resp = response.await()
+ logger.info("Received this response $resp")
+ resp.result == true
+ }
+ },
+ seedSupplier = { seedReference.get() }, hashrateCallback = { _, _ -> true }, sslOptions = null,
+ )
+ runBlocking {
+ server.start()
+ }
+ server.launch {
+ while (true) {
+ server.launch {
+ try {
+ val response = client.sendRequest(
+ JSONRPCRequest(
+ id = idCounter.incrementAndGet(),
+ method = "eth_getWork",
+ params = arrayOf()
+ )
+ ).await()
+ val result = response.result as List<*>
+ val powHash = Bytes32.fromHexString(result[0] as String)
+ val seed = Bytes32.fromHexString(result[1] as String)
+ val difficulty = UInt256.fromHexString(result[2] as String)
+ val blockNumber = Bytes.fromHexString(result[3] as String).toLong()
+ seedReference.set(seed)
+ server.setNewWork(PoWInput(difficulty, powHash, blockNumber))
+ } catch (t: Throwable) {
+ logger.error(t.message, t)
+ }
+ }
+ delay(5000)
+ }
+ }
+ Runtime.getRuntime().addShutdownHook(
+ Thread {
+ runBlocking {
+ logger.info("Shutting down...")
+ server.stop()
+ vertx.close()
+ }
+ }
+ )
+}
diff --git a/stratum/proxy/src/main/resources/logback.xml b/stratum/proxy/src/main/resources/logback.xml
new file mode 100644
index 00000000..785de44a
--- /dev/null
+++ b/stratum/proxy/src/main/resources/logback.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
+ file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
+ to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations under the License.
+-->
+<configuration scan="true">
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <!-- encoders are assigned the type
+ ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="info">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/stratum/server/build.gradle b/stratum/server/build.gradle
index a4f4ef48..f13a0a9e 100644
--- a/stratum/server/build.gradle
+++ b/stratum/server/build.gradle
@@ -15,7 +15,9 @@ description = 'Implementation of a Stratum server'
dependencies {
implementation project(':bytes')
+ implementation project(':jsonrpc')
implementation project(':units')
+ implementation project(':eth')
implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation 'com.google.guava:guava'
implementation 'io.vertx:vertx-core'
diff --git a/stratum/server/src/main/kotlin/org/apache/tuweni/stratum/server/JsonRpc.kt b/stratum/server/src/main/kotlin/org/apache/tuweni/stratum/server/JsonRpc.kt
index 8b365453..379bae16 100644
--- a/stratum/server/src/main/kotlin/org/apache/tuweni/stratum/server/JsonRpc.kt
+++ b/stratum/server/src/main/kotlin/org/apache/tuweni/stratum/server/JsonRpc.kt
@@ -29,9 +29,9 @@ data class JsonRpcRequest(
@JsonProperty("id") val id: String
) {
- fun bytes32(i: Int): Bytes32 = Bytes32.fromHexString(params[i] as String)
+ fun bytes32(i: Int): Bytes32 = Bytes32.fromHexStringLenient(params[i] as String)
- fun bytes(i: Int): Bytes = Bytes.fromHexString(params[i] as String)
+ fun bytes(i: Int): Bytes = Bytes.fromHexStringLenient(params[i] as String)
}
data class JsonRpcSuccessResponse(
diff --git a/stratum/server/src/main/kotlin/org/apache/tuweni/stratum/server/StratumProtocol.kt b/stratum/server/src/main/kotlin/org/apache/tuweni/stratum/server/StratumProtocol.kt
index 64b0857b..e7fa881a 100644
--- a/stratum/server/src/main/kotlin/org/apache/tuweni/stratum/server/StratumProtocol.kt
+++ b/stratum/server/src/main/kotlin/org/apache/tuweni/stratum/server/StratumProtocol.kt
@@ -18,6 +18,8 @@ package org.apache.tuweni.stratum.server
import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.databind.json.JsonMapper
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
import org.apache.tuweni.bytes.Bytes
import org.apache.tuweni.bytes.Bytes32
import org.slf4j.LoggerFactory
@@ -25,6 +27,7 @@ import java.io.IOException
import java.time.Instant
import java.util.ArrayList
import java.util.Random
+import kotlin.coroutines.CoroutineContext
/**
* Handler capable of taking care of a connection to a Stratum server according to a specific flavor of the Stratum protocol.
@@ -77,8 +80,9 @@ class Stratum1Protocol(
timeValue.slice(timeValue.size() - 4, 4).toShortHexString()
},
private val subscriptionIdCreator: () -> String = { createSubscriptionID() },
- private val submitCallback: (PoWSolution) -> (Boolean),
+ private val submitCallback: suspend (PoWSolution) -> (Boolean),
private val seedSupplier: () -> Bytes32,
+ private val coroutineContext: CoroutineContext,
) : StratumProtocol {
private var currentInput: PoWInput? = null
private val activeConnections: MutableList<StratumConnection> = ArrayList()
@@ -184,9 +188,11 @@ class Stratum1Protocol(
)
currentInput?.prePowHash?.equals(solution.powHash)?.let {
if (it) {
- val result = submitCallback(solution)
- val response = mapper.writeValueAsString(JsonRpcSuccessResponse(message.id, result = result))
- conn.send(response + "\n")
+ CoroutineScope(coroutineContext).launch {
+ val result = submitCallback(solution)
+ val response = mapper.writeValueAsString(JsonRpcSuccessResponse(message.id, result = result))
+ conn.send(response + "\n")
+ }
}
}
}
@@ -217,9 +223,10 @@ class Stratum1Protocol(
* This protocol allows miners to submit EthHash solutions over a persistent TCP connection.
*/
class Stratum1EthProxyProtocol(
- private val submitCallback: (PoWSolution) -> Boolean,
+ private val submitCallback: suspend (PoWSolution) -> Boolean,
private val seedSupplier: () -> Bytes32,
private val hashrateCallback: (Bytes, Long) -> Boolean,
+ private val coroutineContext: CoroutineContext,
) : StratumProtocol {
companion object {
@@ -248,9 +255,9 @@ class Stratum1EthProxyProtocol(
private fun sendNewWork(conn: StratumConnection, id: String) {
val input = currentInput ?: return
- val result = mutableListOf(
+ val result: List<String> = mutableListOf(
input.prePowHash.toHexString(),
- seedSupplier(),
+ seedSupplier().toHexString(),
input.target.toHexString()
)
val req = JsonRpcSuccessResponse(id = id, result = result)
@@ -295,9 +302,11 @@ class Stratum1EthProxyProtocol(
)
currentInput?.prePowHash?.equals(solution.powHash)?.let {
if (it) {
- val result = submitCallback(solution)
- val response = mapper.writeValueAsString(JsonRpcSuccessResponse(id = req.id, result = result))
- conn.send(response + "\n")
+ CoroutineScope(coroutineContext).launch {
+ val result = submitCallback(solution)
+ val response = mapper.writeValueAsString(JsonRpcSuccessResponse(id = req.id, result = result))
+ conn.send(response + "\n")
+ }
}
}
}
diff --git a/stratum/server/src/main/kotlin/org/apache/tuweni/stratum/server/StratumServer.kt b/stratum/server/src/main/kotlin/org/apache/tuweni/stratum/server/StratumServer.kt
index abffb57d..81fcc1be 100644
--- a/stratum/server/src/main/kotlin/org/apache/tuweni/stratum/server/StratumServer.kt
+++ b/stratum/server/src/main/kotlin/org/apache/tuweni/stratum/server/StratumServer.kt
@@ -24,11 +24,15 @@ import io.vertx.core.net.NetServerOptions
import io.vertx.core.net.NetSocket
import io.vertx.core.net.SelfSignedCertificate
import io.vertx.kotlin.coroutines.await
+import io.vertx.kotlin.coroutines.dispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.apache.tuweni.bytes.Bytes
import org.apache.tuweni.bytes.Bytes32
import org.slf4j.LoggerFactory
import java.util.concurrent.atomic.AtomicBoolean
+import kotlin.coroutines.CoroutineContext
/**
* Simple main function to run the server with a self-signed certificate.
@@ -59,23 +63,32 @@ class StratumServer(
val networkInterface: String,
private val sslOptions: KeyCertOptions?,
extranonce: String = "",
- submitCallback: (PoWSolution) -> Boolean,
+ submitCallback: suspend (PoWSolution) -> Boolean,
seedSupplier: () -> Bytes32,
hashrateCallback: (Bytes, Long) -> Boolean,
-) {
+ override val coroutineContext: CoroutineContext = vertx.dispatcher(),
+) : CoroutineScope {
companion object {
val logger = LoggerFactory.getLogger(StratumServer::class.java)
}
private val protocols = arrayOf(
- Stratum1EthProxyProtocol(submitCallback, seedSupplier, hashrateCallback),
- Stratum1Protocol(extranonce, submitCallback = submitCallback, seedSupplier = seedSupplier)
+ Stratum1EthProxyProtocol(submitCallback, seedSupplier, hashrateCallback, this.coroutineContext),
+ Stratum1Protocol(extranonce, submitCallback = submitCallback, seedSupplier = seedSupplier, coroutineContext = this.coroutineContext)
)
private val started = AtomicBoolean(false)
private var tcpServer: NetServer? = null
+ fun setNewWork(powInput: PoWInput) {
+ for (protocol in protocols) {
+ launch {
+ protocol.setCurrentWorkTask(powInput)
+ }
+ }
+ }
+
suspend fun start() {
if (started.compareAndSet(false, true)) {
val options = NetServerOptions().setPort(port).setHost(networkInterface).setTcpKeepAlive(true)
diff --git a/stratum/server/src/test/kotlin/org/apache/tuweni/stratum/server/StratumProtocolTest.kt b/stratum/server/src/test/kotlin/org/apache/tuweni/stratum/server/StratumProtocolTest.kt
index 65de35f6..db6a8001 100644
--- a/stratum/server/src/test/kotlin/org/apache/tuweni/stratum/server/StratumProtocolTest.kt
+++ b/stratum/server/src/test/kotlin/org/apache/tuweni/stratum/server/StratumProtocolTest.kt
@@ -16,6 +16,7 @@
*/
package org.apache.tuweni.stratum.server
+import kotlinx.coroutines.Dispatchers
import org.apache.tuweni.bytes.Bytes32
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertTrue
@@ -25,7 +26,10 @@ class StratumProtocolTest {
@Test
fun testStratum1CanHandle() {
- val protocol = Stratum1Protocol("", submitCallback = { true }, seedSupplier = Bytes32::random)
+ val protocol = Stratum1Protocol(
+ "", submitCallback = { true }, seedSupplier = Bytes32::random,
+ coroutineContext = Dispatchers.Default
+ )
val conn = StratumConnection(emptyArray(), {}, {})
assertFalse(protocol.canHandle("", conn))
assertFalse(protocol.canHandle("\"mining.subscribe", conn))
@@ -38,7 +42,8 @@ class StratumProtocolTest {
val protocol = Stratum1EthProxyProtocol(
submitCallback = { true },
seedSupplier = Bytes32::random,
- hashrateCallback = { _, _ -> true }
+ hashrateCallback = { _, _ -> true },
+ Dispatchers.Default,
)
val conn = StratumConnection(emptyArray(), {}, {})
assertFalse(protocol.canHandle("", conn))
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tuweni.apache.org
For additional commands, e-mail: commits-help@tuweni.apache.org