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 <anto...@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-unsubscr...@tuweni.apache.org
For additional commands, e-mail: commits-h...@tuweni.apache.org

Reply via email to