problem: tx broadcast breaks call (and causes timeout) if it's already broadcasted
This commit is contained in:
@@ -17,6 +17,7 @@ package io.emeraldpay.dshackle.rpc
|
||||
|
||||
|
||||
import io.emeraldpay.api.proto.BlockchainOuterClass
|
||||
import io.emeraldpay.dshackle.quorum.BroadcastQuorum
|
||||
import io.emeraldpay.dshackle.test.TestingCommons
|
||||
import io.emeraldpay.dshackle.quorum.AlwaysQuorum
|
||||
import io.emeraldpay.dshackle.upstream.CachingEthereumApi
|
||||
@@ -27,6 +28,9 @@ import io.emeraldpay.dshackle.upstream.Upstream
|
||||
import io.emeraldpay.dshackle.upstream.Upstreams
|
||||
import io.emeraldpay.grpc.Chain
|
||||
import io.infinitape.etherjar.rpc.ReactorRpcClient
|
||||
import io.infinitape.etherjar.rpc.RpcException
|
||||
import io.infinitape.etherjar.rpc.RpcResponseError
|
||||
import io.infinitape.etherjar.rpc.RpcResponseException
|
||||
import reactor.core.publisher.Mono
|
||||
import reactor.test.StepVerifier
|
||||
import spock.lang.Specification
|
||||
@@ -110,10 +114,11 @@ class NativeCallSpec extends Specification {
|
||||
|
||||
when:
|
||||
def t1 = System.currentTimeMillis()
|
||||
nativeCall.executeOnRemote(call).block(Duration.ofSeconds(2))
|
||||
def resp = nativeCall.executeOnRemote(call).block(Duration.ofSeconds(2))
|
||||
def delta = System.currentTimeMillis() - t1
|
||||
then:
|
||||
delta >= 100
|
||||
delta > 95 // should be 100, but sometimes gives less ???
|
||||
new String(resp.payload) == '{"jsonrpc":"2.0","id":1,"result":"bar"}'
|
||||
}
|
||||
|
||||
def "One call has no pause"() {
|
||||
@@ -329,4 +334,35 @@ class NativeCallSpec extends Specification {
|
||||
1 * quorum.record(_, _)
|
||||
1 * quorum.getResult()
|
||||
}
|
||||
|
||||
def "Send raw retries 3 times"() {
|
||||
setup:
|
||||
def quorum = Spy(new BroadcastQuorum(TestingCommons.rpcConverter(), 3))
|
||||
|
||||
def upstreams = Stub(Upstreams)
|
||||
ReactorRpcClient rpcClient = Stub(ReactorRpcClient)
|
||||
def apiMock = TestingCommons.api(rpcClient)
|
||||
apiMock.upstream = Stub(Upstream)
|
||||
|
||||
apiMock.answer("eth_sendRawTransaction", ["0x1234"],
|
||||
"0x4b66b555df9faed6f0711f2104d183736c8e2dc7434626dd2622e243f041d41b", 1)
|
||||
apiMock.answer("eth_sendRawTransaction", ["0x1234"], null, 10,
|
||||
new RpcException(RpcResponseError.CODE_INVALID_REQUEST, "Transaction with the same hash was already imported"))
|
||||
// apiMock.answer("eth_sendRawTransaction", ["0x1234"],
|
||||
// new RpcResponseError(RpcResponseError.CODE_INVALID_REQUEST, "Transaction with the same hash was already imported"), 10)
|
||||
|
||||
def nativeCall = new NativeCall(upstreams, TestingCommons.objectMapper())
|
||||
def call = new NativeCall.CallContext(1, TestingCommons.aggregatedUpstream(apiMock),
|
||||
Selector.empty, quorum,
|
||||
new NativeCall.ParsedCallDetails("eth_sendRawTransaction", ["0x1234"]))
|
||||
|
||||
|
||||
when:
|
||||
def resp = nativeCall.executeOnRemote(call).block(Duration.ofSeconds(2))
|
||||
def act = objectMapper.readValue(resp.payload, Map)
|
||||
then:
|
||||
act == [jsonrpc:"2.0", id:1, result: "0x4b66b555df9faed6f0711f2104d183736c8e2dc7434626dd2622e243f041d41b"]
|
||||
1 * quorum.record(_ as byte[], _)
|
||||
2 * quorum.record(_ as RpcException, _)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import io.emeraldpay.grpc.Chain
|
||||
import io.grpc.stub.StreamObserver
|
||||
import io.infinitape.etherjar.rpc.ReactorRpcClient
|
||||
import io.infinitape.etherjar.rpc.RpcClient
|
||||
import io.infinitape.etherjar.rpc.RpcException
|
||||
import io.infinitape.etherjar.rpc.RpcResponseError
|
||||
import io.infinitape.etherjar.rpc.json.ResponseJson
|
||||
import org.jetbrains.annotations.NotNull
|
||||
@@ -60,9 +61,13 @@ class EthereumApiMock extends DirectEthereumApi {
|
||||
if (predefined.exception != null) {
|
||||
predefined.onCalled()
|
||||
predefined.print()
|
||||
throw predefined.exception
|
||||
return Mono.error(predefined.exception)
|
||||
}
|
||||
if (predefined.result instanceof RpcResponseError) {
|
||||
json.error = predefined.result
|
||||
} else {
|
||||
json.result = predefined.result
|
||||
}
|
||||
json.result = predefined.result
|
||||
} else {
|
||||
log.error("Method ${method} with ${params} is not mocked")
|
||||
json.error = new RpcResponseError(-32601, "Method ${method} with ${params} is not mocked")
|
||||
|
||||
Reference in New Issue
Block a user