Support beacon chain (#436)

This commit is contained in:
KirillPamPam
2024-03-15 17:46:29 +04:00
committed by GitHub
parent d5414f947e
commit d44b72ec69
152 changed files with 2498 additions and 1382 deletions

View File

@@ -22,7 +22,7 @@ import io.emeraldpay.dshackle.Chain
import io.emeraldpay.dshackle.config.ProxyConfig
import io.emeraldpay.dshackle.monitoring.accesslog.AccessHandlerHttp
import io.emeraldpay.dshackle.rpc.NativeCall
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcException
import io.micrometer.core.instrument.Counter
import reactor.core.publisher.Flux
@@ -73,7 +73,7 @@ class HttpHandlerSpec extends Specification {
def "Return error on invalid request"() {
setup:
ReadRpcJson read = Mock(ReadRpcJson) {
1 * apply(_) >> { throw new RpcException(-32123, "test", new JsonRpcResponse.NumberId(4)) }
1 * apply(_) >> { throw new RpcException(-32123, "test", new ChainResponse.NumberId(4)) }
}
Counter errorMetric = Mock(Counter) {
1 * increment()

View File

@@ -17,7 +17,7 @@
package io.emeraldpay.dshackle.proxy
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcException
import spock.lang.Specification
@@ -192,7 +192,7 @@ class ReadRpcJsonSpec extends Specification {
def t = thrown(RpcException)
t.code == -32600
t.rpcMessage.toLowerCase() == "jsonrpc version is not set"
t.details == new JsonRpcResponse.NumberId(2)
t.details == new ChainResponse.NumberId(2)
}
def "Error if jsonrpc version is invalid"() {
@@ -202,7 +202,7 @@ class ReadRpcJsonSpec extends Specification {
def t = thrown(RpcException)
t.code == -32600
t.rpcMessage.toLowerCase() == "unsupported json rpc version: 3.0"
t.details == new JsonRpcResponse.NumberId(2)
t.details == new ChainResponse.NumberId(2)
}
def "Error if method is not set"() {
@@ -212,7 +212,7 @@ class ReadRpcJsonSpec extends Specification {
def t = thrown(RpcException)
t.code == -32600
t.rpcMessage.toLowerCase() == "method is not set"
t.details == new JsonRpcResponse.NumberId(2)
t.details == new ChainResponse.NumberId(2)
}
def "Error if params is not array"() {
@@ -222,7 +222,7 @@ class ReadRpcJsonSpec extends Specification {
def t = thrown(RpcException)
t.code == -32600
t.rpcMessage.toLowerCase() == "params must be an array"
t.details == new JsonRpcResponse.NumberId(2)
t.details == new ChainResponse.NumberId(2)
}
def "Error if json is broken"() {

View File

@@ -16,8 +16,8 @@
package io.emeraldpay.dshackle.quorum
import io.emeraldpay.dshackle.upstream.Upstream
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcException
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainException
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.signature.ResponseSigner
import spock.lang.Specification
@@ -28,7 +28,7 @@ class AlwaysQuorumSpec extends Specification {
def quorum = new AlwaysQuorum()
def up = Stub(Upstream)
when:
quorum.record(new JsonRpcException(1, "test"), null, up)
quorum.record(new ChainException(1, "test"), null, up)
then:
quorum.isFailed()
!quorum.isResolved()
@@ -43,7 +43,7 @@ class AlwaysQuorumSpec extends Specification {
def quorum = new AlwaysQuorum()
def up = Stub(Upstream)
when:
quorum.record(new JsonRpcResponse("123".bytes, null), new ResponseSigner.Signature("sig1".bytes, "test", 100), up)
quorum.record(new ChainResponse("123".bytes, null), new ResponseSigner.Signature("sig1".bytes, "test", 100), up)
then:
quorum.isResolved()
quorum.getResponse().getResult() == "123".bytes

View File

@@ -19,8 +19,8 @@ package io.emeraldpay.dshackle.quorum
import com.fasterxml.jackson.databind.ObjectMapper
import io.emeraldpay.dshackle.Global
import io.emeraldpay.dshackle.upstream.Upstream
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcException
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainException
import io.emeraldpay.dshackle.upstream.ChainResponse
import spock.lang.Specification
class BroadcastQuorumSpec extends Specification {
@@ -35,17 +35,17 @@ class BroadcastQuorumSpec extends Specification {
def upstream3 = Stub(Upstream)
when:
q.record(new JsonRpcResponse('"0xeaa972c0d8d1ecd3e34fbbef6d34e06670e745c788bdba31c4234a1762f0378c"'.bytes, null), null, upstream1)
q.record(new ChainResponse('"0xeaa972c0d8d1ecd3e34fbbef6d34e06670e745c788bdba31c4234a1762f0378c"'.bytes, null), null, upstream1)
then:
1 * q.recordValue(_, "0xeaa972c0d8d1ecd3e34fbbef6d34e06670e745c788bdba31c4234a1762f0378c", _, _)
when:
q.record(new JsonRpcResponse('"0xeaa972c0d8d1ecd3e34fbbef6d34e06670e745c788bdba31c4234a1762f0378c"'.bytes, null), null, upstream2)
q.record(new ChainResponse('"0xeaa972c0d8d1ecd3e34fbbef6d34e06670e745c788bdba31c4234a1762f0378c"'.bytes, null), null, upstream2)
then:
1 * q.recordValue(_, "0xeaa972c0d8d1ecd3e34fbbef6d34e06670e745c788bdba31c4234a1762f0378c", _, _)
when:
q.record(new JsonRpcException(1, "Nonce too low"), null, upstream3)
q.record(new ChainException(1, "Nonce too low"), null, upstream3)
then:
1 * q.recordError(_, _, _)
objectMapper.readValue(q.response.getResult(), Object) == "0xeaa972c0d8d1ecd3e34fbbef6d34e06670e745c788bdba31c4234a1762f0378c"
@@ -59,17 +59,17 @@ class BroadcastQuorumSpec extends Specification {
def upstream3 = Stub(Upstream)
when:
q.record(new JsonRpcException(1, "Internal error"), null, upstream1)
q.record(new ChainException(1, "Internal error"), null, upstream1)
then:
1 * q.recordError(_, _, _)
when:
q.record(new JsonRpcResponse('"0xeaa972c0d8d1ecd3e34fbbef6d34e06670e745c788bdba31c4234a1762f0378c"'.bytes, null), null, upstream2)
q.record(new ChainResponse('"0xeaa972c0d8d1ecd3e34fbbef6d34e06670e745c788bdba31c4234a1762f0378c"'.bytes, null), null, upstream2)
then:
1 * q.recordValue(_, "0xeaa972c0d8d1ecd3e34fbbef6d34e06670e745c788bdba31c4234a1762f0378c", _, _)
when:
q.record(new JsonRpcException(1, "Nonce too low"), null, upstream3)
q.record(new ChainException(1, "Nonce too low"), null, upstream3)
then:
1 * q.recordError(_, _, _)
q.isResolved()
@@ -81,9 +81,9 @@ class BroadcastQuorumSpec extends Specification {
def quorum = new BroadcastQuorum()
def up = Stub(Upstream)
when:
quorum.record(new JsonRpcException(1, "test 1"), null, up)
quorum.record(new JsonRpcException(1, "test 2"), null, up)
quorum.record(new JsonRpcException(1, "test 3"), null, up)
quorum.record(new ChainException(1, "test 1"), null, up)
quorum.record(new ChainException(1, "test 2"), null, up)
quorum.record(new ChainException(1, "test 3"), null, up)
then:
quorum.isFailed()
!quorum.isResolved()

View File

@@ -1,8 +1,8 @@
package io.emeraldpay.dshackle.quorum
import io.emeraldpay.dshackle.upstream.Upstream
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcException
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainException
import io.emeraldpay.dshackle.upstream.ChainResponse
import spock.lang.Specification
class MaximumValueQuorumSpec extends Specification {
@@ -19,9 +19,9 @@ class MaximumValueQuorumSpec extends Specification {
}
when:
def quorum = new MaximumValueQuorum()
quorum.record(new JsonRpcResponse('"0x137"'.bytes, null), null, up)
quorum.record(new JsonRpcResponse('"0x138"'.bytes, null), null, up1)
quorum.record(new JsonRpcResponse('"0x139"'.bytes, null), null, up2)
quorum.record(new ChainResponse('"0x137"'.bytes, null), null, up)
quorum.record(new ChainResponse('"0x138"'.bytes, null), null, up1)
quorum.record(new ChainResponse('"0x139"'.bytes, null), null, up2)
then:
quorum.response.result == '"0x139"'.bytes
quorum.resolvedBy.size() == 1
@@ -42,9 +42,9 @@ class MaximumValueQuorumSpec extends Specification {
}
when:
def quorum = new MaximumValueQuorum()
quorum.record(new JsonRpcResponse('"0x137"'.bytes, null), null, up)
quorum.record(new JsonRpcResponse('"0x138"'.bytes, null), null, up1)
quorum.record(new JsonRpcException(10, "error"), null, up2)
quorum.record(new ChainResponse('"0x137"'.bytes, null), null, up)
quorum.record(new ChainResponse('"0x138"'.bytes, null), null, up1)
quorum.record(new ChainException(10, "error"), null, up2)
then:
quorum.response.result == '"0x138"'.bytes
quorum.isResolved()
@@ -65,13 +65,13 @@ class MaximumValueQuorumSpec extends Specification {
}
when:
def quorum = new MaximumValueQuorum()
quorum.record(new JsonRpcException(10, "error1"), null, up)
quorum.record(new JsonRpcException(10, "error2"), null, up1)
quorum.record(new JsonRpcException(10, "error3"), null, up2)
quorum.record(new ChainException(10, "error1"), null, up)
quorum.record(new ChainException(10, "error2"), null, up1)
quorum.record(new ChainException(10, "error3"), null, up2)
then:
!quorum.isResolved()
quorum.isFailed()
quorum.error == new JsonRpcException(10, "error3").error
quorum.error == new ChainException(10, "error3").error
quorum.resolvedBy.size() == 3
}

View File

@@ -17,8 +17,8 @@
package io.emeraldpay.dshackle.quorum
import io.emeraldpay.dshackle.upstream.Upstream
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcException
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainException
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.signature.ResponseSigner
import spock.lang.Specification
@@ -31,7 +31,7 @@ class NotLaggingQuorumSpec extends Specification {
def quorum = new NotLaggingQuorum(1)
when:
quorum.record(new JsonRpcResponse(value, null), null, up)
quorum.record(new ChainResponse(value, null), null, up)
then:
1 * up.getLag() >> 0
quorum.isResolved()
@@ -46,7 +46,7 @@ class NotLaggingQuorumSpec extends Specification {
def quorum = new NotLaggingQuorum(1)
when:
quorum.record(new JsonRpcResponse(value, null), new ResponseSigner.Signature("sig1".bytes, "test", 100), up)
quorum.record(new ChainResponse(value, null), new ResponseSigner.Signature("sig1".bytes, "test", 100), up)
then:
1 * up.getLag() >> 0
quorum.isResolved()
@@ -62,7 +62,7 @@ class NotLaggingQuorumSpec extends Specification {
def quorum = new NotLaggingQuorum(1)
when:
quorum.record(new JsonRpcResponse(value, null), null, up)
quorum.record(new ChainResponse(value, null), null, up)
then:
1 * up.getLag() >> 1
quorum.isResolved()
@@ -77,7 +77,7 @@ class NotLaggingQuorumSpec extends Specification {
def quorum = new NotLaggingQuorum(1)
when:
quorum.record(new JsonRpcResponse(value, null), null, up)
quorum.record(new ChainResponse(value, null), null, up)
then:
1 * up.getLag() >> 2
!quorum.isResolved()
@@ -91,7 +91,7 @@ class NotLaggingQuorumSpec extends Specification {
def quorum = new NotLaggingQuorum(1)
when:
quorum.record(new JsonRpcException(-100, "test error"), null, up)
quorum.record(new ChainException(-100, "test error"), null, up)
then:
1 * up.getLag() >> 1
!quorum.isResolved()

View File

@@ -1,8 +1,8 @@
package io.emeraldpay.dshackle.quorum
import io.emeraldpay.dshackle.upstream.Upstream
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcException
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainException
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.signature.ResponseSigner
import spock.lang.Specification
@@ -20,7 +20,7 @@ class NotNullQuorumSpec extends Specification {
1 * getId() >> "id2"
}
def value = "null".getBytes()
def response = new JsonRpcResponse(value, null)
def response = new ChainResponse(value, null)
def quorum = new NotNullQuorum()
when:
@@ -53,15 +53,15 @@ class NotNullQuorumSpec extends Specification {
def quorum = new NotNullQuorum()
when:
quorum.record(new JsonRpcException(10, "error"), null, up)
quorum.record(new JsonRpcException(10, "error"), null, up1)
quorum.record(new JsonRpcException(10, "error"), null, up2)
quorum.record(new JsonRpcException(10, "error"), null, up)
quorum.record(new ChainException(10, "error"), null, up)
quorum.record(new ChainException(10, "error"), null, up1)
quorum.record(new ChainException(10, "error"), null, up2)
quorum.record(new ChainException(10, "error"), null, up)
then:
quorum.isFailed()
!quorum.isResolved()
quorum.error == new JsonRpcException(10, "error").error
quorum.error == new ChainException(10, "error").error
}
def "Resolve if one of upstream responds with value"() {
@@ -79,10 +79,10 @@ class NotNullQuorumSpec extends Specification {
def quorum = new NotNullQuorum()
when:
def res = quorum.record(new JsonRpcResponse(value, null), new ResponseSigner.Signature("sig1".bytes, "test", 100), up)
quorum.record(new JsonRpcException(10, "error"), new ResponseSigner.Signature("sig1".bytes, "test", 100), up1)
quorum.record(new JsonRpcException(10, "error"), new ResponseSigner.Signature("sig1".bytes, "test", 100), up2)
quorum.record(new JsonRpcException(10, "error"), new ResponseSigner.Signature("sig1".bytes, "test", 100), up)
def res = quorum.record(new ChainResponse(value, null), new ResponseSigner.Signature("sig1".bytes, "test", 100), up)
quorum.record(new ChainException(10, "error"), new ResponseSigner.Signature("sig1".bytes, "test", 100), up1)
quorum.record(new ChainException(10, "error"), new ResponseSigner.Signature("sig1".bytes, "test", 100), up2)
quorum.record(new ChainException(10, "error"), new ResponseSigner.Signature("sig1".bytes, "test", 100), up)
then:
!res

View File

@@ -21,9 +21,9 @@ import io.emeraldpay.dshackle.reader.Reader
import io.emeraldpay.dshackle.upstream.FilteredApis
import io.emeraldpay.dshackle.upstream.Selector
import io.emeraldpay.dshackle.upstream.Upstream
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcException
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainException
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcException
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcResponseError
@@ -34,7 +34,7 @@ import spock.lang.Specification
import java.time.Duration
class QuorumRpcReaderSpec extends Specification {
class QuorumRequestReaderSpec extends Specification {
def "always-quorum - get the result if ok"() {
setup:
@@ -43,17 +43,17 @@ class QuorumRpcReaderSpec extends Specification {
_ * getId() >> "id"
_ * getRole() >> UpstreamsConfig.UpstreamRole.PRIMARY
1 * getIngressReader() >> Mock(Reader) {
1 * read(new JsonRpcRequest("eth_test", new ListParams())) >> Mono.just(JsonRpcResponse.ok("1"))
1 * read(new ChainRequest("eth_test", new ListParams())) >> Mono.just(ChainResponse.ok("1"))
}
}
def apis = new FilteredApis(
Chain.ETHEREUM__MAINNET,
[up], Selector.empty
)
def reader = new QuorumRpcReader(apis, new AlwaysQuorum(), Stub(Tracer))
def reader = new QuorumRequestReader(apis, new AlwaysQuorum(), Stub(Tracer))
when:
def act = reader.read(new JsonRpcRequest("eth_test", new ListParams()))
def act = reader.read(new ChainRequest("eth_test", new ListParams()))
.map {
new String(it.value)
}
@@ -68,8 +68,8 @@ class QuorumRpcReaderSpec extends Specification {
def "always-quorum - return upstream error returned"() {
setup:
def api = Mock(Reader) {
1 * read(new JsonRpcRequest("eth_test", new ListParams())) >>> [
Mono.just(JsonRpcResponse.error(1, "test"))
1 * read(new ChainRequest("eth_test", new ListParams())) >>> [
Mono.just(ChainResponse.error(1, "test"))
]
}
def up = Mock(Upstream) {
@@ -82,10 +82,10 @@ class QuorumRpcReaderSpec extends Specification {
Chain.ETHEREUM__MAINNET,
[up], Selector.empty
)
def reader = new QuorumRpcReader(apis, new AlwaysQuorum(), Stub(Tracer))
def reader = new QuorumRequestReader(apis, new AlwaysQuorum(), Stub(Tracer))
when:
def act = reader.read(new JsonRpcRequest("eth_test", new ListParams()))
def act = reader.read(new ChainRequest("eth_test", new ListParams()))
.map {
new String(it.value)
}
@@ -93,7 +93,7 @@ class QuorumRpcReaderSpec extends Specification {
then:
StepVerifier.create(act)
.expectErrorMatches {
it instanceof JsonRpcException && ((JsonRpcException) it).error.message == "test"
it instanceof ChainException && ((ChainException) it).error.message == "test"
}
.verify(Duration.ofSeconds(1))
}
@@ -101,7 +101,7 @@ class QuorumRpcReaderSpec extends Specification {
def "always-quorum - return upstream error thrown"() {
setup:
def api = Mock(Reader) {
1 * read(new JsonRpcRequest("eth_test", new ListParams())) >>> [
1 * read(new ChainRequest("eth_test", new ListParams())) >>> [
Mono.error(
new RpcException(
RpcResponseError.CODE_UPSTREAM_CONNECTION_ERROR,
@@ -120,10 +120,10 @@ class QuorumRpcReaderSpec extends Specification {
Chain.ETHEREUM__MAINNET,
[up], Selector.empty
)
def reader = new QuorumRpcReader(apis, new AlwaysQuorum(), Stub(Tracer))
def reader = new QuorumRequestReader(apis, new AlwaysQuorum(), Stub(Tracer))
when:
def act = reader.read(new JsonRpcRequest("eth_test", new ListParams()))
def act = reader.read(new ChainRequest("eth_test", new ListParams()))
.map {
new String(it.value)
}
@@ -131,7 +131,7 @@ class QuorumRpcReaderSpec extends Specification {
then:
StepVerifier.create(act)
.expectErrorMatches {
it instanceof JsonRpcException && ((JsonRpcException) it).error.message == "test-123"
it instanceof ChainException && ((ChainException) it).error.message == "test-123"
}
.verify(Duration.ofSeconds(1))
}
@@ -143,9 +143,9 @@ class QuorumRpcReaderSpec extends Specification {
_ * getId() >> "id"
_ * getRole() >> UpstreamsConfig.UpstreamRole.PRIMARY
_ * getIngressReader() >> Mock(Reader) {
2 * read(new JsonRpcRequest("eth_test", new ListParams())) >>> [
Mono.just(JsonRpcResponse.ok("null")),
Mono.just(JsonRpcResponse.ok("1"))
2 * read(new ChainRequest("eth_test", new ListParams())) >>> [
Mono.just(ChainResponse.ok("null")),
Mono.just(ChainResponse.ok("1"))
]
}
}
@@ -153,10 +153,10 @@ class QuorumRpcReaderSpec extends Specification {
Chain.ETHEREUM__MAINNET,
[up], Selector.empty
)
def reader = new QuorumRpcReader(apis, new NotNullQuorum(), Stub(Tracer))
def reader = new QuorumRequestReader(apis, new NotNullQuorum(), Stub(Tracer))
when:
def act = reader.read(new JsonRpcRequest("eth_test", new ListParams()))
def act = reader.read(new ChainRequest("eth_test", new ListParams()))
.map {
new String(it.value)
}
@@ -176,9 +176,9 @@ class QuorumRpcReaderSpec extends Specification {
_ * getId() >> "id"
_ * getRole() >> UpstreamsConfig.UpstreamRole.PRIMARY
_ * getIngressReader() >> Mock(Reader) {
2 * read(new JsonRpcRequest("eth_test", new ListParams())) >>> [
Mono.just(JsonRpcResponse.error(1, "test")),
Mono.just(JsonRpcResponse.ok("1"))
2 * read(new ChainRequest("eth_test", new ListParams())) >>> [
Mono.just(ChainResponse.error(1, "test")),
Mono.just(ChainResponse.ok("1"))
]
}
}
@@ -186,10 +186,10 @@ class QuorumRpcReaderSpec extends Specification {
Chain.ETHEREUM__MAINNET,
[up], Selector.empty
)
def reader = new QuorumRpcReader(apis, new NotNullQuorum(), Stub(Tracer))
def reader = new QuorumRequestReader(apis, new NotNullQuorum(), Stub(Tracer))
when:
def act = reader.read(new JsonRpcRequest("eth_test", new ListParams()))
def act = reader.read(new ChainRequest("eth_test", new ListParams()))
.map {
new String(it.value)
}
@@ -204,9 +204,9 @@ class QuorumRpcReaderSpec extends Specification {
def "non-empty-quorum - error if all failed"() {
setup:
def api = Mock(Reader) {
2 * read(new JsonRpcRequest("eth_test", new ListParams())) >>> [
Mono.just(JsonRpcResponse.error(1, "test")),
Mono.just(JsonRpcResponse.error(1, "test")),
2 * read(new ChainRequest("eth_test", new ListParams())) >>> [
Mono.just(ChainResponse.error(1, "test")),
Mono.just(ChainResponse.error(1, "test")),
]
}
def up = Mock(Upstream) {
@@ -219,10 +219,10 @@ class QuorumRpcReaderSpec extends Specification {
Chain.ETHEREUM__MAINNET,
[up], Selector.empty
)
def reader = new QuorumRpcReader(apis, new NotNullQuorum(), Stub(Tracer))
def reader = new QuorumRequestReader(apis, new NotNullQuorum(), Stub(Tracer))
when:
def act = reader.read(new JsonRpcRequest("eth_test", new ListParams()))
def act = reader.read(new ChainRequest("eth_test", new ListParams()))
.map {
new String(it.value)
}
@@ -236,8 +236,8 @@ class QuorumRpcReaderSpec extends Specification {
def "always-quorum - error if failed"() {
setup:
def api = Mock(Reader) {
1 * read(new JsonRpcRequest("eth_test", new ListParams())) >>> [
Mono.just(JsonRpcResponse.error(1, "test error")),
1 * read(new ChainRequest("eth_test", new ListParams())) >>> [
Mono.just(ChainResponse.error(1, "test error")),
]
}
def up = Mock(Upstream) {
@@ -250,10 +250,10 @@ class QuorumRpcReaderSpec extends Specification {
Chain.ETHEREUM__MAINNET,
[up], Selector.empty
)
def reader = new QuorumRpcReader(apis, new AlwaysQuorum(), Stub(Tracer))
def reader = new QuorumRequestReader(apis, new AlwaysQuorum(), Stub(Tracer))
when:
def act = reader.read(new JsonRpcRequest("eth_test", new ListParams()))
def act = reader.read(new ChainRequest("eth_test", new ListParams()))
.map {
new String(it.value)
}
@@ -262,7 +262,7 @@ class QuorumRpcReaderSpec extends Specification {
StepVerifier.create(act)
.expectErrorMatches { t ->
println("Error: $t.class / $t.message")
t instanceof JsonRpcException && t.message == "test error" && t.error.code == 1
t instanceof ChainException && t.message == "test error" && t.error.code == 1
}
.verify(Duration.ofSeconds(2))
}
@@ -275,8 +275,8 @@ class QuorumRpcReaderSpec extends Specification {
_ * isAvailable() >> true
_ * getRole() >> UpstreamsConfig.UpstreamRole.PRIMARY
_ * getIngressReader() >> Mock(Reader) {
_ * read(new JsonRpcRequest("eth_test", new ListParams())) >>> [
Mono.just(JsonRpcResponse.error(-3010, "test")),
_ * read(new ChainRequest("eth_test", new ListParams())) >>> [
Mono.just(ChainResponse.error(-3010, "test")),
]
}
}
@@ -284,10 +284,10 @@ class QuorumRpcReaderSpec extends Specification {
Chain.ETHEREUM__MAINNET,
[up], Selector.empty
)
def reader = new QuorumRpcReader(apis, new NotLaggingQuorum(1), Stub(Tracer))
def reader = new QuorumRequestReader(apis, new NotLaggingQuorum(1), Stub(Tracer))
when:
def act = reader.read(new JsonRpcRequest("eth_test", new ListParams()))
def act = reader.read(new ChainRequest("eth_test", new ListParams()))
then:
StepVerifier.create(act)
@@ -310,10 +310,10 @@ class QuorumRpcReaderSpec extends Specification {
Chain.ETHEREUM__MAINNET,
[up], Selector.empty
)
def reader = new QuorumRpcReader(apis, new AlwaysQuorum(), Stub(Tracer))
def reader = new QuorumRequestReader(apis, new AlwaysQuorum(), Stub(Tracer))
when:
def act = reader.read(new JsonRpcRequest("eth_test", new ListParams()))
def act = reader.read(new ChainRequest("eth_test", new ListParams()))
.map {
new String(it.value)
}

View File

@@ -17,7 +17,7 @@ package io.emeraldpay.dshackle.quorum
import io.emeraldpay.dshackle.upstream.Upstream
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.signature.ResponseSigner
import org.jetbrains.annotations.NotNull
import org.jetbrains.annotations.Nullable
@@ -67,7 +67,7 @@ class ValueAwareQuorumSpec extends Specification {
}
@Override
void recordValue(@NotNull JsonRpcResponse response, @Nullable Object responseValue, @Nullable ResponseSigner.Signature signature, @NotNull Upstream upstream) {
void recordValue(@NotNull ChainResponse response, @Nullable Object responseValue, @Nullable ResponseSigner.Signature signature, @NotNull Upstream upstream) {
}
@@ -89,8 +89,8 @@ class ValueAwareQuorumSpec extends Specification {
}
@Override
JsonRpcResponse getResponse() {
return new JsonRpcResponse(null, null)
ChainResponse getResponse() {
return new ChainResponse(null, null)
}
@Override

View File

@@ -3,9 +3,9 @@ package io.emeraldpay.dshackle.reader
import io.emeraldpay.dshackle.quorum.BroadcastQuorum
import io.emeraldpay.dshackle.upstream.Selector
import io.emeraldpay.dshackle.upstream.Upstream
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcException
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainException
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import org.springframework.cloud.sleuth.Tracer
import reactor.core.publisher.Mono
@@ -23,29 +23,29 @@ class BroadcastReaderSpec extends Specification {
1 * isAvailable() >> true
_ * getId() >> "id"
1 * getIngressReader() >> Mock(Reader) {
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.just(new JsonRpcResponse(result, null))
1 * read(new ChainRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.just(new ChainResponse(result, null))
}
}
def up1 = Mock(Upstream) {
1 * isAvailable() >> true
_ * getId() >> "id"
1 * getIngressReader() >> Mock(Reader) {
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.just(new JsonRpcResponse(result, null))
1 * read(new ChainRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.just(new ChainResponse(result, null))
}
}
def up2 = Mock(Upstream) {
1 * isAvailable() >> true
_ * getId() >> "id"
1 * getIngressReader() >> Mock(Reader) {
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.just(new JsonRpcResponse(result, null))
1 * read(new ChainRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.just(new ChainResponse(result, null))
}
}
def reader = new BroadcastReader([up, up1, up2], new Selector.EmptyMatcher(), null, new BroadcastQuorum(), Stub(Tracer))
when:
def act = reader.read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"])))
def act = reader.read(new ChainRequest("eth_sendRawTransaction", new ListParams(["0x1"])))
then:
StepVerifier.create(act)
.expectNextMatches {
@@ -62,28 +62,28 @@ class BroadcastReaderSpec extends Specification {
1 * isAvailable() >> true
_ * getId() >> "id"
1 * getIngressReader() >> Mock(Reader) {
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.just(new JsonRpcResponse(result, null))
1 * read(new ChainRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.just(new ChainResponse(result, null))
}
}
def up1 = Mock(Upstream) {
1 * isAvailable() >> true
_ * getId() >> "id"
1 * getIngressReader() >> Mock(Reader) {
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.error(new JsonRpcException(1, "too low"))
1 * read(new ChainRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.error(new ChainException(1, "too low"))
}
}
def up2 = Mock(Upstream) {
1 * isAvailable() >> true
_ * getId() >> "id"
1 * getIngressReader() >> Mock(Reader) {
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.error(new JsonRpcException(1, "too low")) }
1 * read(new ChainRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.error(new ChainException(1, "too low")) }
}
def reader = new BroadcastReader([up, up1, up2], new Selector.EmptyMatcher(), null, new BroadcastQuorum(), Stub(Tracer))
when:
def act = reader.read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"])))
def act = reader.read(new ChainRequest("eth_sendRawTransaction", new ListParams(["0x1"])))
then:
StepVerifier.create(act)
.expectNextMatches {
@@ -100,8 +100,8 @@ class BroadcastReaderSpec extends Specification {
1 * isAvailable() >> true
_ * getId() >> "id"
1 * getIngressReader() >> Mock(Reader) {
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.just(new JsonRpcResponse(result, null))
1 * read(new ChainRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.just(new ChainResponse(result, null))
}
}
def up1 = Mock(Upstream) {
@@ -116,7 +116,7 @@ class BroadcastReaderSpec extends Specification {
}
def reader = new BroadcastReader([up, up1, up2], new Selector.EmptyMatcher(), null, new BroadcastQuorum(), Stub(Tracer))
when:
def act = reader.read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"])))
def act = reader.read(new ChainRequest("eth_sendRawTransaction", new ListParams(["0x1"])))
then:
StepVerifier.create(act)
.expectNextMatches {
@@ -132,32 +132,32 @@ class BroadcastReaderSpec extends Specification {
1 * isAvailable() >> true
_ * getId() >> "id"
1 * getIngressReader() >> Mock(Reader) {
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.error(new JsonRpcException(1, "too low"))
1 * read(new ChainRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.error(new ChainException(1, "too low"))
}
}
def up1 = Mock(Upstream) {
1 * isAvailable() >> true
_ * getId() >> "id"
1 * getIngressReader() >> Mock(Reader) {
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.error(new JsonRpcException(1, "too low"))
1 * read(new ChainRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.error(new ChainException(1, "too low"))
}
}
def up2 = Mock(Upstream) {
1 * isAvailable() >> true
_ * getId() >> "id"
1 * getIngressReader() >> Mock(Reader) {
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.error(new JsonRpcException(1, "too low"))
1 * read(new ChainRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
Mono.error(new ChainException(1, "too low"))
}
}
def reader = new BroadcastReader([up, up1, up2], new Selector.EmptyMatcher(), null, new BroadcastQuorum(), Stub(Tracer))
when:
def act = reader.read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"])))
def act = reader.read(new ChainRequest("eth_sendRawTransaction", new ListParams(["0x1"])))
then:
StepVerifier.create(act)
.expectError(JsonRpcException.class)
.expectError(ChainException.class)
.verify(Duration.ofSeconds(3))
}
@@ -181,8 +181,8 @@ class BroadcastReaderSpec extends Specification {
def reader = new BroadcastReader([up, up1, up2], new Selector.EmptyMatcher(), null, new BroadcastQuorum(), Stub(Tracer))
when:
def act = reader
.read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"])))
.switchIfEmpty(Mono.just(new RpcReader.Result(new byte[0], null, 0, null, null)))
.read(new ChainRequest("eth_sendRawTransaction", new ListParams(["0x1"])))
.switchIfEmpty(Mono.just(new RequestReader.Result(new byte[0], null, 0, null, null)))
then:
StepVerifier.create(act)
.expectErrorMessage("Unhandled Upstream error")

View File

@@ -26,8 +26,8 @@ import io.emeraldpay.dshackle.config.CacheConfig
import io.emeraldpay.dshackle.config.MainConfig
import io.emeraldpay.dshackle.quorum.AlwaysQuorum
import io.emeraldpay.dshackle.reader.Reader
import io.emeraldpay.dshackle.reader.RpcReader
import io.emeraldpay.dshackle.reader.RpcReaderFactory
import io.emeraldpay.dshackle.reader.RequestReader
import io.emeraldpay.dshackle.reader.RequestReaderFactory
import io.emeraldpay.dshackle.startup.UpstreamChangeEvent
import io.emeraldpay.dshackle.test.MultistreamHolderMock
import io.emeraldpay.dshackle.test.TestingCommons
@@ -35,10 +35,6 @@ import io.emeraldpay.dshackle.upstream.*
import io.emeraldpay.dshackle.upstream.calls.DefaultEthereumMethods
import io.emeraldpay.dshackle.upstream.calls.ManagedCallMethods
import io.emeraldpay.dshackle.upstream.generic.GenericUpstream
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcError
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcException
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import io.emeraldpay.dshackle.upstream.signature.ResponseSigner
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcException
@@ -76,7 +72,7 @@ class NativeCallSpec extends Specification {
def "Tries router first"() {
def routedApi = Mock(Reader) {
1 * read(new JsonRpcRequest("eth_test", new ListParams())) >> Mono.just(new JsonRpcResponse("1".bytes, null))
1 * read(new ChainRequest("eth_test", new ListParams())) >> Mono.just(new ChainResponse("1".bytes, null))
}
def upstream = Mock(Multistream) {
1 * getLocalReader() >> Mono.just(routedApi)
@@ -97,7 +93,7 @@ class NativeCallSpec extends Specification {
def "Return error if router denied the requests"() {
def routedApi = Mock(Reader) {
1 * read(new JsonRpcRequest("eth_test", new ListParams())) >> Mono.error(new RpcException(RpcResponseError.CODE_METHOD_NOT_EXIST, "Test message"))
1 * read(new ChainRequest("eth_test", new ListParams())) >> Mono.error(new RpcException(RpcResponseError.CODE_METHOD_NOT_EXIST, "Test message"))
}
def upstream = Mock(Multistream) {
1 * getLocalReader() >> Mono.just(routedApi)
@@ -129,9 +125,9 @@ class NativeCallSpec extends Specification {
}
def nativeCall = nativeCall()
nativeCall.rpcReaderFactory = Mock(RpcReaderFactory) {
1 * create(_) >> Mock(RpcReader) {
1 * read(_) >> Mono.just(new RpcReader.Result("\"foo\"".bytes, null, 1, ups, null))
nativeCall.requestReaderFactory = Mock(RequestReaderFactory) {
1 * create(_) >> Mock(RequestReader) {
1 * read(_) >> Mono.just(new RequestReader.Result("\"foo\"".bytes, null, 1, ups, null))
}
}
def call = new NativeCall.ValidCallContext(1, 10, TestingCommons.multistream(TestingCommons.api()), Selector.empty, quorum,
@@ -150,10 +146,10 @@ class NativeCallSpec extends Specification {
def quorum = new AlwaysQuorum()
def nativeCall = nativeCall()
nativeCall.rpcReaderFactory = Mock(RpcReaderFactory) {
1 * create(_) >> Mock(RpcReader) {
nativeCall.requestReaderFactory = Mock(RequestReaderFactory) {
1 * create(_) >> Mock(RequestReader) {
1 * attempts() >> new AtomicInteger(1)
1 * read(new JsonRpcRequest("eth_test", new ListParams(), 10)) >> Mono.empty()
1 * read(new ChainRequest("eth_test", new ListParams(), 10)) >> Mono.empty()
}
}
def call = new NativeCall.ValidCallContext(1, 10, TestingCommons.multistream(TestingCommons.api()), Selector.empty, quorum,
@@ -175,10 +171,10 @@ class NativeCallSpec extends Specification {
def quorum = new AlwaysQuorum()
def nativeCall = nativeCall()
nativeCall.rpcReaderFactory = Mock(RpcReaderFactory) {
1 * create(_) >> Mock(RpcReader) {
1 * read(new JsonRpcRequest("eth_test", new ListParams(), 10)) >> Mono.error(
new JsonRpcException(JsonRpcResponse.Id.from(12), new JsonRpcError(-32123, "Foo Bar", "Foo Bar Baz"), null, true, null)
nativeCall.requestReaderFactory = Mock(RequestReaderFactory) {
1 * create(_) >> Mock(RequestReader) {
1 * read(new ChainRequest("eth_test", new ListParams(), 10)) >> Mono.error(
new ChainException(ChainResponse.Id.from(12), new ChainCallError(-32123, "Foo Bar", "Foo Bar Baz"), null, true, null)
)
}
}
@@ -338,7 +334,7 @@ class NativeCallSpec extends Specification {
id == 1
nonce == 10
payload.method == "eth_test"
payload.params == "[]"
payload.params == new ListParams()
}
}
@@ -354,6 +350,7 @@ class NativeCallSpec extends Specification {
.addItems(
BlockchainOuterClass.NativeCallItem.newBuilder()
.setId(1)
.setPayload(ByteString.copyFromUtf8("[]"))
.setMethod("eth_test")
)
.build()
@@ -365,7 +362,7 @@ class NativeCallSpec extends Specification {
with(act[0]) {
id == 1
payload.method == "eth_test"
payload.params == ""
payload.params == new ListParams()
}
}
@@ -419,6 +416,7 @@ class NativeCallSpec extends Specification {
.addItems(
BlockchainOuterClass.NativeCallItem.newBuilder()
.setId(1)
.setPayload(ByteString.copyFromUtf8("[]"))
.setMethod("foo_bar")
)
.build()
@@ -457,6 +455,7 @@ class NativeCallSpec extends Specification {
.addItems(
BlockchainOuterClass.NativeCallItem.newBuilder()
.setId(1)
.setPayload(ByteString.copyFromUtf8("[]"))
.setMethod("eth_newFilter")
)
.build()
@@ -487,6 +486,7 @@ class NativeCallSpec extends Specification {
.addItems(
BlockchainOuterClass.NativeCallItem.newBuilder()
.setId(1)
.setPayload(ByteString.copyFromUtf8("[]"))
.setMethod("eth_getFilterChanges")
)
.build()
@@ -517,6 +517,7 @@ class NativeCallSpec extends Specification {
.addItems(
BlockchainOuterClass.NativeCallItem.newBuilder()
.setId(1)
.setPayload(ByteString.copyFromUtf8("[]"))
.setMethod("eth_uninstallFilter")
)
.build()
@@ -532,7 +533,7 @@ class NativeCallSpec extends Specification {
setup:
def nativeCall = nativeCall()
def ctx = new NativeCall.ValidCallContext(1, null, Stub(Multistream), Selector.empty, new AlwaysQuorum(),
new NativeCall.RawCallDetails("eth_test", "[]"), "reqId", 1)
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
when:
def act = nativeCall.parseParams(ctx)
then:
@@ -545,7 +546,7 @@ class NativeCallSpec extends Specification {
setup:
def nativeCall = nativeCall()
def ctx = new NativeCall.ValidCallContext(1, null, Stub(Multistream), Selector.empty, new AlwaysQuorum(),
new NativeCall.RawCallDetails("eth_test", ""), "reqId", 1)
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
when:
def act = nativeCall.parseParams(ctx)
then:
@@ -558,7 +559,7 @@ class NativeCallSpec extends Specification {
setup:
def nativeCall = nativeCall()
def ctx = new NativeCall.ValidCallContext(1, null, Stub(Multistream), Selector.empty, new AlwaysQuorum(),
new NativeCall.RawCallDetails("eth_test", "[false]"), "reqId", 1)
new NativeCall.ParsedCallDetails("eth_test", new ListParams(false)), "reqId", 1)
when:
def act = nativeCall.parseParams(ctx)
then:
@@ -571,7 +572,7 @@ class NativeCallSpec extends Specification {
setup:
def nativeCall = nativeCall()
def ctx = new NativeCall.ValidCallContext(1, null, Stub(Multistream), Selector.empty, new AlwaysQuorum(),
new NativeCall.RawCallDetails("eth_test", "[false, 123]"), "reqId", 1)
new NativeCall.ParsedCallDetails("eth_test", new ListParams(false, 123)), "reqId", 1)
when:
def act = nativeCall.parseParams(ctx)
then:
@@ -584,7 +585,7 @@ class NativeCallSpec extends Specification {
setup:
def nativeCall = nativeCall()
def ctx = new NativeCall.ValidCallContext(1, null, Stub(Multistream), Selector.empty, new AlwaysQuorum(),
new NativeCall.RawCallDetails("eth_getFilterUpdates", '["0xabcd"]'),
new NativeCall.ParsedCallDetails("eth_getFilterUpdates", new ListParams("0xabcd")),
new NativeCall.WithFilterIdDecorator(), new NativeCall.NoneResultDecorator(), null, false, "reqId", 1)
when:
def act = nativeCall.parseParams(ctx)
@@ -613,9 +614,9 @@ class NativeCallSpec extends Specification {
_ * it.observeChains() >> Flux.empty()
}
def nativeCall = nativeCall(multistreamHolder)
nativeCall.rpcReaderFactory = Mock(RpcReaderFactory) {
1 * create(_) >> Mock(RpcReader) {
1 * read(_) >> Mono.just(new RpcReader.Result("\"0xab\"".bytes, null, 1, ups, null))
nativeCall.requestReaderFactory = Mock(RequestReaderFactory) {
1 * create(_) >> Mock(RequestReader) {
1 * read(_) >> Mono.just(new RequestReader.Result("\"0xab\"".bytes, null, 1, ups, null))
}
}
def call = new NativeCall.ValidCallContext(1, 10, multistream, Selector.empty, quorum,
@@ -649,9 +650,9 @@ class NativeCallSpec extends Specification {
_ * it.observeChains() >> Flux.empty()
}
def nativeCall = nativeCall(multistreamHolder)
nativeCall.rpcReaderFactory = Mock(RpcReaderFactory) {
1 * create(_) >> Mock(RpcReader) {
1 * read(_) >> Mono.just(new RpcReader.Result("\"0xab\"".bytes, null, 1, ups, null))
nativeCall.requestReaderFactory = Mock(RequestReaderFactory) {
1 * create(_) >> Mock(RequestReader) {
1 * read(_) >> Mono.just(new RequestReader.Result("\"0xab\"".bytes, null, 1, ups, null))
}
}
def call = new NativeCall.ValidCallContext(1, 10, multistream, Selector.empty, quorum,

View File

@@ -21,9 +21,9 @@ import com.google.protobuf.ByteString
import io.emeraldpay.api.proto.BlockchainOuterClass
import io.emeraldpay.dshackle.Global
import io.emeraldpay.dshackle.reader.Reader
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcError
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainCallError
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcResponseError
import io.grpc.stub.StreamObserver
import io.netty.buffer.ByteBuf
@@ -56,7 +56,7 @@ import java.util.function.BiFunction
import java.util.function.Consumer
import java.util.function.Predicate
class ApiReaderMock implements Reader<JsonRpcRequest, JsonRpcResponse> {
class ApiReaderMock implements Reader<ChainRequest, ChainResponse> {
private static final Logger log = LoggerFactory.getLogger(this)
List<PredefinedResponse> predefined = []
@@ -79,11 +79,11 @@ class ApiReaderMock implements Reader<JsonRpcRequest, JsonRpcResponse> {
}
@Override
Mono<JsonRpcResponse> read(JsonRpcRequest request, boolean required = true) {
Callable<JsonRpcResponse> call = {
Mono<ChainResponse> read(ChainRequest request, boolean required = true) {
Callable<ChainResponse> call = {
def predefined = predefined.find { it.isSame(request.method, request.params.list) }
byte[] result = null
JsonRpcError error = null
ChainCallError error = null
calls.incrementAndGet()
if (predefined != null) {
if (predefined.exception != null) {
@@ -93,7 +93,7 @@ class ApiReaderMock implements Reader<JsonRpcRequest, JsonRpcResponse> {
}
if (predefined.result instanceof RpcResponseError) {
((RpcResponseError) predefined.result).with { err ->
error = new JsonRpcError(err.code, err.message)
error = new ChainCallError(err.code, err.message)
}
} else {
// ResponseJson json = new ResponseJson<Object, Integer>(id: 1, result: predefined.result)
@@ -106,16 +106,16 @@ class ApiReaderMock implements Reader<JsonRpcRequest, JsonRpcResponse> {
if (!required) {
return null
}
error = new JsonRpcError(-32601, "Method ${request.method} with ${request.params} is not mocked")
error = new ChainCallError(-32601, "Method ${request.method} with ${request.params} is not mocked")
}
return new JsonRpcResponse(result, error, JsonRpcResponse.Id.from(request.id), null, null, null)
} as Callable<JsonRpcResponse>
return new ChainResponse(result, error, ChainResponse.Id.from(request.id), null, null, null)
} as Callable<ChainResponse>
return Mono.fromCallable(call)
}
def nativeCall(BlockchainOuterClass.NativeCallRequest request, StreamObserver<BlockchainOuterClass.NativeCallReplyItem> responseObserver) {
request.itemsList.forEach { req ->
JsonRpcResponse resp = read(new JsonRpcRequest(req.method, objectMapper.readerFor(List).readValue(req.payload.toByteArray())))
ChainResponse resp = read(new ChainRequest(req.method, objectMapper.readerFor(List).readValue(req.payload.toByteArray())))
.block(Duration.ofSeconds(5))
def proto = BlockchainOuterClass.NativeCallReplyItem.newBuilder()
.setId(req.id)
@@ -170,7 +170,7 @@ class ApiReaderMock implements Reader<JsonRpcRequest, JsonRpcResponse> {
class WebsocketApi {
private final ApiReaderMock api
private Sinks.Many<JsonRpcResponse> responses = Sinks
private Sinks.Many<ChainResponse> responses = Sinks
.many()
.unicast()
.onBackpressureBuffer()
@@ -202,10 +202,10 @@ class ApiReaderMock implements Reader<JsonRpcRequest, JsonRpcResponse> {
class WebsocketInboundMock implements WebsocketInbound {
private final Flux<JsonRpcResponse> responses
private final Flux<ChainResponse> responses
private final Flux<String> jsonResponses
WebsocketInboundMock(Flux<JsonRpcResponse> responses, Flux<String> jsonResponses) {
WebsocketInboundMock(Flux<ChainResponse> responses, Flux<String> jsonResponses) {
this.responses = responses
this.jsonResponses = jsonResponses
}
@@ -260,9 +260,9 @@ class ApiReaderMock implements Reader<JsonRpcRequest, JsonRpcResponse> {
class WebsocketOutboundMock implements WebsocketOutbound {
private final ApiReaderMock api
private final Sinks.Many<JsonRpcResponse> responses
private final Sinks.Many<ChainResponse> responses
WebsocketOutboundMock(ApiReaderMock api, Sinks.Many<JsonRpcResponse> responses) {
WebsocketOutboundMock(ApiReaderMock api, Sinks.Many<ChainResponse> responses) {
this.api = api
this.responses = responses
}
@@ -280,9 +280,9 @@ class ApiReaderMock implements Reader<JsonRpcRequest, JsonRpcResponse> {
private void handle(Publisher<ByteBuf> dataStream) {
Flux.from(dataStream)
.map { it ->
Global.objectMapper.readValue(new ByteBufInputStream(it), JsonRpcRequest)
Global.objectMapper.readValue(new ByteBufInputStream(it), ChainRequest)
}
.flatMap { JsonRpcRequest request ->
.flatMap { ChainRequest request ->
api.read(request, false)
}
.doOnNext {

View File

@@ -4,17 +4,16 @@ import io.emeraldpay.dshackle.Chain
import io.emeraldpay.dshackle.reader.Reader
import io.emeraldpay.dshackle.upstream.DefaultUpstream
import io.emeraldpay.dshackle.upstream.Head
import io.emeraldpay.dshackle.upstream.ethereum.EthereumUpstreamValidator
import io.emeraldpay.dshackle.upstream.generic.connectors.ConnectorFactory
import io.emeraldpay.dshackle.upstream.generic.connectors.GenericConnector
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
class ConnectorFactoryMock implements ConnectorFactory {
Reader<JsonRpcRequest, JsonRpcResponse> api
Reader<ChainRequest, ChainResponse> api
Head head
ConnectorFactoryMock(Reader<JsonRpcRequest, JsonRpcResponse> api, Head head) {
ConnectorFactoryMock(Reader<ChainRequest, ChainResponse> api, Head head) {
this.api = api
this.head = head
}

View File

@@ -17,11 +17,11 @@
package io.emeraldpay.dshackle.test
import io.emeraldpay.dshackle.reader.Reader
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
import reactor.core.publisher.Mono
class EthereumApiStub implements Reader<JsonRpcRequest, JsonRpcResponse> {
class EthereumApiStub implements Reader<ChainRequest, ChainResponse> {
private String id
@@ -39,7 +39,7 @@ class EthereumApiStub implements Reader<JsonRpcRequest, JsonRpcResponse> {
}
@Override
Mono<JsonRpcResponse> read(JsonRpcRequest key) {
Mono<ChainResponse> read(ChainRequest key) {
return Mono.error(new Exception("Not implemented in mock"))
}

View File

@@ -5,16 +5,16 @@ import io.emeraldpay.dshackle.upstream.Head
import io.emeraldpay.dshackle.upstream.IngressSubscription
import io.emeraldpay.dshackle.upstream.ethereum.NoEthereumIngressSubscription
import io.emeraldpay.dshackle.upstream.generic.connectors.GenericConnector
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
import reactor.core.publisher.Flux
class GenericConnectorMock implements GenericConnector {
Reader<JsonRpcRequest, JsonRpcResponse> api
Reader<ChainRequest, ChainResponse> api
Head head
Flux<Boolean> liveness
GenericConnectorMock(Reader<JsonRpcRequest, JsonRpcResponse> api, Head head) {
GenericConnectorMock(Reader<ChainRequest, ChainResponse> api, Head head) {
this.api = api
this.head = head
this.liveness = Flux.just(false)
@@ -26,7 +26,7 @@ class GenericConnectorMock implements GenericConnector {
}
@Override
Reader<JsonRpcRequest, JsonRpcResponse> getIngressReader() {
Reader<ChainRequest, ChainResponse> getIngressReader() {
return this.api
}

View File

@@ -27,8 +27,8 @@ import io.emeraldpay.dshackle.upstream.LowerBoundBlockDetector
import io.emeraldpay.dshackle.upstream.UpstreamAvailability
import io.emeraldpay.dshackle.upstream.calls.*
import io.emeraldpay.dshackle.upstream.generic.GenericUpstream
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
import org.jetbrains.annotations.NotNull
import org.reactivestreams.Publisher
@@ -43,27 +43,27 @@ class GenericUpstreamMock extends GenericUpstream {
])
}
GenericUpstreamMock(@NotNull Chain chain, @NotNull Reader<JsonRpcRequest, JsonRpcResponse> api) {
GenericUpstreamMock(@NotNull Chain chain, @NotNull Reader<ChainRequest, ChainResponse> api) {
this(chain, api, allMethods())
}
GenericUpstreamMock(@NotNull String id, @NotNull Chain chain, @NotNull Reader<JsonRpcRequest, JsonRpcResponse> api, Map<String, String> labels) {
GenericUpstreamMock(@NotNull String id, @NotNull Chain chain, @NotNull Reader<ChainRequest, ChainResponse> api, Map<String, String> labels) {
this(id, chain, api, allMethods(), labels)
}
GenericUpstreamMock(@NotNull String id, @NotNull Chain chain, @NotNull Reader<JsonRpcRequest, JsonRpcResponse> api) {
GenericUpstreamMock(@NotNull String id, @NotNull Chain chain, @NotNull Reader<ChainRequest, ChainResponse> api) {
this(id, chain, api, allMethods())
}
GenericUpstreamMock(@NotNull Chain chain, @NotNull Reader<JsonRpcRequest, JsonRpcResponse> api, CallMethods methods) {
GenericUpstreamMock(@NotNull Chain chain, @NotNull Reader<ChainRequest, ChainResponse> api, CallMethods methods) {
this("test", chain, api, methods)
}
GenericUpstreamMock(@NotNull String id, @NotNull Chain chain, @NotNull Reader<JsonRpcRequest, JsonRpcResponse> api, CallMethods methods) {
GenericUpstreamMock(@NotNull String id, @NotNull Chain chain, @NotNull Reader<ChainRequest, ChainResponse> api, CallMethods methods) {
this(id, chain, api, methods, Collections.<String, String>emptyMap())
}
GenericUpstreamMock(@NotNull String id, @NotNull Chain chain, @NotNull Reader<JsonRpcRequest, JsonRpcResponse> api, CallMethods methods, Map<String, String> labels) {
GenericUpstreamMock(@NotNull String id, @NotNull Chain chain, @NotNull Reader<ChainRequest, ChainResponse> api, CallMethods methods, Map<String, String> labels) {
super(id,
chain,
(byte)id.hashCode(),

View File

@@ -33,8 +33,8 @@ import io.emeraldpay.dshackle.upstream.calls.DirectCallMethods
import io.emeraldpay.dshackle.upstream.ethereum.EthereumChainSpecific
import io.emeraldpay.dshackle.upstream.ethereum.json.BlockJson
import io.emeraldpay.dshackle.upstream.generic.GenericMultistream
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.ethereum.domain.BlockHash
import io.emeraldpay.dshackle.upstream.ethereum.domain.TransactionId
import io.emeraldpay.dshackle.upstream.ethereum.json.TransactionRefJson
@@ -68,27 +68,27 @@ class TestingCommons {
return new GenericUpstreamMock(id, Chain.ETHEREUM__MAINNET, api(), Collections.singletonMap("provider", provider))
}
static GenericUpstreamMock upstream(String id, Reader<JsonRpcRequest, JsonRpcResponse> api) {
static GenericUpstreamMock upstream(String id, Reader<ChainRequest, ChainResponse> api) {
return new GenericUpstreamMock(id, Chain.ETHEREUM__MAINNET, api)
}
static GenericUpstreamMock upstream(Reader<JsonRpcRequest, JsonRpcResponse> api) {
static GenericUpstreamMock upstream(Reader<ChainRequest, ChainResponse> api) {
return new GenericUpstreamMock(Chain.ETHEREUM__MAINNET, api)
}
static GenericUpstreamMock upstream(Reader<JsonRpcRequest, JsonRpcResponse> api, String method) {
static GenericUpstreamMock upstream(Reader<ChainRequest, ChainResponse> api, String method) {
return upstream(api, [method])
}
static GenericUpstreamMock upstream(Reader<JsonRpcRequest, JsonRpcResponse> api, List<String> methods) {
static GenericUpstreamMock upstream(Reader<ChainRequest, ChainResponse> api, List<String> methods) {
return new GenericUpstreamMock(Chain.ETHEREUM__MAINNET, api, new DirectCallMethods(methods))
}
static GenericUpstreamMock upstream(Reader<JsonRpcRequest, JsonRpcResponse> api, CallMethods callMethods) {
static GenericUpstreamMock upstream(Reader<ChainRequest, ChainResponse> api, CallMethods callMethods) {
return new GenericUpstreamMock(Chain.ETHEREUM__MAINNET, api, callMethods)
}
static Multistream multistream(Reader<JsonRpcRequest, JsonRpcResponse> api) {
static Multistream multistream(Reader<ChainRequest, ChainResponse> api) {
return multistream(upstream(api))
}
@@ -109,7 +109,7 @@ class TestingCommons {
}
static Multistream emptyMultistream() {
return multistream(new EmptyReader<JsonRpcRequest, JsonRpcResponse>())
return multistream(new EmptyReader<ChainRequest, ChainResponse>())
}
static CachesFactory emptyCaches() {

View File

@@ -19,7 +19,6 @@ package io.emeraldpay.dshackle.upstream
import io.emeraldpay.dshackle.Chain
import io.emeraldpay.dshackle.config.ChainsConfig
import io.emeraldpay.dshackle.config.UpstreamsConfig
import io.emeraldpay.dshackle.reader.JsonRpcHttpReader
import io.emeraldpay.dshackle.startup.QuorumForLabels
import io.emeraldpay.dshackle.test.EthereumApiStub
import io.emeraldpay.dshackle.test.TestingCommons
@@ -29,7 +28,6 @@ import io.emeraldpay.dshackle.upstream.generic.connectors.GenericConnectorFactor
import io.emeraldpay.dshackle.upstream.forkchoice.MostWorkForkChoice
import reactor.core.scheduler.Schedulers
import reactor.test.StepVerifier
import spock.lang.Retry
import io.emeraldpay.dshackle.foundation.ChainOptions
import spock.lang.Specification
@@ -54,7 +52,7 @@ class FilteredApisSpec extends Specification {
].collect {
def httpFactory = Mock(HttpFactory) {
create(_, _) >> Stub(JsonRpcHttpReader)
create(_, _) >> Stub(HttpReader)
}
def connectorFactory = new GenericConnectorFactory(
GenericConnectorFactory.ConnectorMode.RPC_ONLY,

View File

@@ -33,8 +33,6 @@ import io.emeraldpay.dshackle.upstream.generic.GenericUpstream
import io.emeraldpay.dshackle.upstream.generic.GenericMultistream
import io.emeraldpay.dshackle.upstream.ethereum.json.BlockJson
import io.emeraldpay.dshackle.upstream.grpc.GenericGrpcUpstream
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.starknet.StarknetChainSpecific
import io.emeraldpay.dshackle.upstream.ethereum.domain.BlockHash
import io.emeraldpay.dshackle.upstream.ethereum.json.TransactionRefJson
@@ -376,7 +374,7 @@ class MultistreamSpec extends Specification {
@NotNull
@Override
Mono<Reader<JsonRpcRequest, JsonRpcResponse>> getLocalReader() {
Mono<Reader<ChainRequest, ChainResponse>> getLocalReader() {
return null
}

View File

@@ -16,8 +16,8 @@
package io.emeraldpay.dshackle.upstream.bitcoin
import io.emeraldpay.dshackle.reader.Reader
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import reactor.core.publisher.Mono
import reactor.core.scheduler.Schedulers
@@ -79,13 +79,13 @@ class BitcoinRpcHeadSpec extends Specification {
"""
def api = Mock(Reader) {
_ * read(new JsonRpcRequest("getbestblockhash", new ListParams())) >>> [
Mono.just(new JsonRpcResponse("\"$hash1\"".bytes, null)),
Mono.just(new JsonRpcResponse("\"$hash1\"".bytes, null)),
Mono.just(new JsonRpcResponse("\"$hash2\"".bytes, null))
_ * read(new ChainRequest("getbestblockhash", new ListParams())) >>> [
Mono.just(new ChainResponse("\"$hash1\"".bytes, null)),
Mono.just(new ChainResponse("\"$hash1\"".bytes, null)),
Mono.just(new ChainResponse("\"$hash2\"".bytes, null))
]
_ * read(new JsonRpcRequest("getblock", new ListParams([hash1]))) >> Mono.just(new JsonRpcResponse(block1.bytes, null))
_ * read(new JsonRpcRequest("getblock", new ListParams([hash2]))) >> Mono.just(new JsonRpcResponse(block2.bytes, null))
_ * read(new ChainRequest("getblock", new ListParams([hash1]))) >> Mono.just(new ChainResponse(block1.bytes, null))
_ * read(new ChainRequest("getblock", new ListParams([hash2]))) >> Mono.just(new ChainResponse(block2.bytes, null))
}
BitcoinRpcHead head = new BitcoinRpcHead(api, new ExtractBlock(), Duration.ofMillis(200), Schedulers.boundedElastic())

View File

@@ -16,8 +16,8 @@
package io.emeraldpay.dshackle.upstream.bitcoin
import io.emeraldpay.dshackle.reader.Reader
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import org.bitcoinj.core.Address
import org.bitcoinj.params.MainNetParams
@@ -30,7 +30,7 @@ class RpcUnspentReaderSpec extends Specification {
setup:
def json = this.class.getClassLoader().getResourceAsStream("bitcoin/unspent-one-addr.json").bytes
def rpcReader = Mock(Reader) {
1 * read(new JsonRpcRequest("listunspent", new ListParams([1, 9999999, ["1K7xkspJg7DDKNwzXgoRSDCUxiFsRegsSK"]]))) >> Mono.just(JsonRpcResponse.ok(json))
1 * read(new ChainRequest("listunspent", new ListParams([1, 9999999, ["1K7xkspJg7DDKNwzXgoRSDCUxiFsRegsSK"]]))) >> Mono.just(ChainResponse.ok(json))
}
def upstreams = Mock(BitcoinMultistream) {
1 * getDirectApi(_) >> Mono.just(rpcReader)
@@ -64,7 +64,7 @@ class RpcUnspentReaderSpec extends Specification {
setup:
def json = this.class.getClassLoader().getResourceAsStream("bitcoin/unspent-two-addr.json").bytes
def rpcReader = Mock(Reader) {
1 * read(new JsonRpcRequest("listunspent", new ListParams([1, 9999999, ["35hK24tcLEWcgNA4JxpvbkNkoAcDGqQPsP"]]))) >> Mono.just(JsonRpcResponse.ok(json))
1 * read(new ChainRequest("listunspent", new ListParams([1, 9999999, ["35hK24tcLEWcgNA4JxpvbkNkoAcDGqQPsP"]]))) >> Mono.just(ChainResponse.ok(json))
}
def upstreams = Mock(BitcoinMultistream) {
1 * getDirectApi(_) >> Mono.just(rpcReader)
@@ -99,7 +99,7 @@ class RpcUnspentReaderSpec extends Specification {
setup:
def json = this.class.getClassLoader().getResourceAsStream("bitcoin/unspent-two-addr.json").bytes
def rpcReader = Mock(Reader) {
1 * read(_) >> Mono.just(JsonRpcResponse.ok(json))
1 * read(_) >> Mono.just(ChainResponse.ok(json))
}
def upstreams = Mock(BitcoinMultistream) {
1 * getDirectApi(_) >> Mono.just(rpcReader)

View File

@@ -6,13 +6,12 @@ import io.emeraldpay.dshackle.cache.Caches
import io.emeraldpay.dshackle.cache.CurrentBlockCache
import io.emeraldpay.dshackle.data.BlockId
import io.emeraldpay.dshackle.data.DefaultContainer
import io.emeraldpay.dshackle.reader.RpcReader
import io.emeraldpay.dshackle.reader.RpcReaderFactory
import io.emeraldpay.dshackle.reader.RequestReader
import io.emeraldpay.dshackle.reader.RequestReaderFactory
import io.emeraldpay.dshackle.test.TestingCommons
import io.emeraldpay.dshackle.upstream.*
import io.emeraldpay.dshackle.upstream.calls.DefaultEthereumMethods
import io.emeraldpay.dshackle.upstream.ethereum.json.BlockJson
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import io.emeraldpay.dshackle.upstream.ethereum.domain.Address
import io.emeraldpay.dshackle.upstream.ethereum.domain.BlockHash
@@ -51,10 +50,10 @@ class EthereumDirectReaderSpec extends Specification {
EthereumDirectReader reader = new EthereumDirectReader(
Stub(Multistream), Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
)
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
1 * create(_) >> Mock(RpcReader) {
1 * read(new JsonRpcRequest("eth_getBlockByHash", new ListParams([hash1, false]))) >> Mono.just(
new RpcReader.Result(
reader.requestReaderFactory = Mock(RequestReaderFactory) {
1 * create(_) >> Mock(RequestReader) {
1 * read(new ChainRequest("eth_getBlockByHash", new ListParams([hash1, false]))) >> Mono.just(
new RequestReader.Result(
Global.objectMapper.writeValueAsBytes(json), null, 1, resolver, null)
)
}
@@ -78,10 +77,10 @@ class EthereumDirectReaderSpec extends Specification {
EthereumDirectReader reader = new EthereumDirectReader(
Stub(Multistream), Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
)
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
1 * create(_) >> Mock(RpcReader) {
1 * read(new JsonRpcRequest("eth_getBlockByHash", new ListParams([hash1, false]))) >> Mono.just(
new RpcReader.Result(
reader.requestReaderFactory = Mock(RequestReaderFactory) {
1 * create(_) >> Mock(RequestReader) {
1 * read(new ChainRequest("eth_getBlockByHash", new ListParams([hash1, false]))) >> Mono.just(
new RequestReader.Result(
Global.objectMapper.writeValueAsBytes(null), null, 1, resolver, null
)
)
@@ -111,10 +110,10 @@ class EthereumDirectReaderSpec extends Specification {
EthereumDirectReader reader = new EthereumDirectReader(
Stub(Multistream), Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
)
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
1 * create(_) >> Mock(RpcReader) {
1 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x64", false]))) >> Mono.just(
new RpcReader.Result(
reader.requestReaderFactory = Mock(RequestReaderFactory) {
1 * create(_) >> Mock(RequestReader) {
1 * read(new ChainRequest("eth_getBlockByNumber", new ListParams(["0x64", false]))) >> Mono.just(
new RequestReader.Result(
Global.objectMapper.writeValueAsBytes(json), null, 1, resolver, null
)
)
@@ -143,10 +142,10 @@ class EthereumDirectReaderSpec extends Specification {
EthereumDirectReader reader = new EthereumDirectReader(
Stub(Multistream), Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
)
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
1 * create(_) >> Mock(RpcReader) {
1 * read(new JsonRpcRequest("eth_getLogs", new ListParams([Map.of("blockHash", hash1)]))) >> Mono.just(
new RpcReader.Result(
reader.requestReaderFactory = Mock(RequestReaderFactory) {
1 * create(_) >> Mock(RequestReader) {
1 * read(new ChainRequest("eth_getLogs", new ListParams([Map.of("blockHash", hash1)]))) >> Mono.just(
new RequestReader.Result(
Global.objectMapper.writeValueAsBytes([json]), null, 1, resolver, null
)
)
@@ -176,10 +175,10 @@ class EthereumDirectReaderSpec extends Specification {
EthereumDirectReader reader = new EthereumDirectReader(
Stub(Multistream), Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
)
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
1 * create(_) >> Mock(RpcReader) {
1 * read(new JsonRpcRequest("eth_getTransactionByHash", new ListParams([hash1]))) >> Mono.just(
new RpcReader.Result(
reader.requestReaderFactory = Mock(RequestReaderFactory) {
1 * create(_) >> Mock(RequestReader) {
1 * read(new ChainRequest("eth_getTransactionByHash", new ListParams([hash1]))) >> Mono.just(
new RequestReader.Result(
Global.objectMapper.writeValueAsBytes(json), null, 1, resolver, null
)
)
@@ -209,10 +208,10 @@ class EthereumDirectReaderSpec extends Specification {
EthereumDirectReader reader = new EthereumDirectReader(
Stub(Multistream), Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
)
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
1 * create(_) >> Mock(RpcReader) {
1 * read(new JsonRpcRequest("eth_getTransactionReceipt", new ListParams([hash1]))) >> Mono.just(
new RpcReader.Result(
reader.requestReaderFactory = Mock(RequestReaderFactory) {
1 * create(_) >> Mock(RequestReader) {
1 * read(new ChainRequest("eth_getTransactionReceipt", new ListParams([hash1]))) >> Mono.just(
new RequestReader.Result(
Global.objectMapper.writeValueAsBytes(json), null, 1, resolver, null
)
)
@@ -243,10 +242,10 @@ class EthereumDirectReaderSpec extends Specification {
EthereumDirectReader reader = new EthereumDirectReader(
Stub(Multistream), caches, new CurrentBlockCache(), calls, TestingCommons.tracerMock()
)
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
1 * create(_) >> Mock(RpcReader) {
1 * read(new JsonRpcRequest("eth_getTransactionReceipt", new ListParams([hash1]))) >> Mono.just(
new RpcReader.Result(
reader.requestReaderFactory = Mock(RequestReaderFactory) {
1 * create(_) >> Mock(RequestReader) {
1 * read(new ChainRequest("eth_getTransactionReceipt", new ListParams([hash1]))) >> Mono.just(
new RequestReader.Result(
Global.objectMapper.writeValueAsBytes(json), null, 1, resolver, null
)
)
@@ -268,10 +267,10 @@ class EthereumDirectReaderSpec extends Specification {
EthereumDirectReader reader = new EthereumDirectReader(
Stub(Multistream), Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
)
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
1 * create(_) >> Mock(RpcReader) {
1 * read(new JsonRpcRequest("eth_getTransactionByHash", new ListParams([hash1]))) >> Mono.just(
new RpcReader.Result(
reader.requestReaderFactory = Mock(RequestReaderFactory) {
1 * create(_) >> Mock(RequestReader) {
1 * read(new ChainRequest("eth_getTransactionByHash", new ListParams([hash1]))) >> Mono.just(
new RequestReader.Result(
Global.objectMapper.writeValueAsBytes(null), null, 1, resolver, null
)
)
@@ -298,10 +297,10 @@ class EthereumDirectReaderSpec extends Specification {
EthereumDirectReader reader = new EthereumDirectReader(
up, Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
)
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
1 * create(_) >> Mock(RpcReader) {
1 * read(new JsonRpcRequest("eth_getBalance", new ListParams([address1, "latest"]))) >> Mono.just(
new RpcReader.Result(
reader.requestReaderFactory = Mock(RequestReaderFactory) {
1 * create(_) >> Mock(RequestReader) {
1 * read(new ChainRequest("eth_getBalance", new ListParams([address1, "latest"]))) >> Mono.just(
new RequestReader.Result(
Global.objectMapper.writeValueAsBytes("0x100"), null, 1, resolver, null
)
)
@@ -329,10 +328,10 @@ class EthereumDirectReaderSpec extends Specification {
EthereumDirectReader reader = new EthereumDirectReader(
up, Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
)
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
1 * create(_) >> Mock(RpcReader) {
1 * read(new JsonRpcRequest("eth_getBalance", new ListParams([address1, "0xa8c9bb"]))) >> Mono.just(
new RpcReader.Result(
reader.requestReaderFactory = Mock(RequestReaderFactory) {
1 * create(_) >> Mock(RequestReader) {
1 * read(new ChainRequest("eth_getBalance", new ListParams([address1, "0xa8c9bb"]))) >> Mono.just(
new RequestReader.Result(
Global.objectMapper.writeValueAsBytes("0x100"), null, 1, resolver, null
)
)
@@ -361,19 +360,19 @@ class EthereumDirectReaderSpec extends Specification {
3 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM__MAINNET, false)
}
def result = Mono.just(
new RpcReader.Result(
new RequestReader.Result(
Global.objectMapper.writeValueAsBytes(json), null, 1, resolver, null)
)
EthereumDirectReader ethereumDirectReader = new EthereumDirectReader(
Stub(Multistream), Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
)
ethereumDirectReader.rpcReaderFactory = Mock(RpcReaderFactory) {
2 * create(_) >> Mock(RpcReader) {
2 * read(new JsonRpcRequest("eth_getBlockByHash", new ListParams([hash1, false]))) >>>
ethereumDirectReader.requestReaderFactory = Mock(RequestReaderFactory) {
2 * create(_) >> Mock(RequestReader) {
2 * read(new ChainRequest("eth_getBlockByHash", new ListParams([hash1, false]))) >>>
[Mono.error(new RuntimeException()), Mono.error(new RuntimeException())]
}
1 * create(_) >> Mock(RpcReader) {
1 * read(new JsonRpcRequest("eth_getBlockByHash", new ListParams([hash1, false]))) >> result
1 * create(_) >> Mock(RequestReader) {
1 * read(new ChainRequest("eth_getBlockByHash", new ListParams([hash1, false]))) >> result
}
}
when:
@@ -401,19 +400,19 @@ class EthereumDirectReaderSpec extends Specification {
3 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM__MAINNET, false)
}
def result = Mono.just(
new RpcReader.Result(
new RequestReader.Result(
Global.objectMapper.writeValueAsBytes(json), null, 1, resolver, null)
)
EthereumDirectReader ethereumDirectReader = new EthereumDirectReader(
Stub(Multistream), Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
)
ethereumDirectReader.rpcReaderFactory = Mock(RpcReaderFactory) {
2 * create(_) >> Mock(RpcReader) {
2 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x64", false]))) >>>
ethereumDirectReader.requestReaderFactory = Mock(RequestReaderFactory) {
2 * create(_) >> Mock(RequestReader) {
2 * read(new ChainRequest("eth_getBlockByNumber", new ListParams(["0x64", false]))) >>>
[Mono.error(new RuntimeException()), Mono.error(new RuntimeException())]
}
1 * create(_) >> Mock(RpcReader) {
1 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x64", false]))) >> result
1 * create(_) >> Mock(RequestReader) {
1 * read(new ChainRequest("eth_getBlockByNumber", new ListParams(["0x64", false]))) >> result
}
}
when:
@@ -440,9 +439,9 @@ class EthereumDirectReaderSpec extends Specification {
EthereumDirectReader reader = new EthereumDirectReader(
up, Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
)
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
4 * create(_) >> Mock(RpcReader) {
4 * read(new JsonRpcRequest("eth_getBalance", new ListParams([address1, "latest"]))) >>>
reader.requestReaderFactory = Mock(RequestReaderFactory) {
4 * create(_) >> Mock(RequestReader) {
4 * read(new ChainRequest("eth_getBalance", new ListParams([address1, "latest"]))) >>>
[Mono.error(new RuntimeException()), Mono.error(new RuntimeException()),
Mono.error(new RuntimeException()), Mono.error(new RuntimeException())]
}

View File

@@ -6,8 +6,8 @@ import io.emeraldpay.dshackle.test.ApiReaderMock
import io.emeraldpay.dshackle.test.TestingCommons
import io.emeraldpay.dshackle.upstream.DefaultUpstream
import io.emeraldpay.dshackle.upstream.ethereum.subscribe.EthereumLabelsDetector
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import kotlin.Pair
import reactor.core.publisher.Mono
@@ -53,14 +53,14 @@ class EthereumLabelsDetectorSpec extends Specification {
setup:
def up = Mock(DefaultUpstream) {
1 * getIngressReader() >> Mock(Reader) {
1 * read(new JsonRpcRequest("web3_clientVersion", new ListParams())) >>
Mono.just(new JsonRpcResponse('no/v1.19.3+e8ac1da4/linux-x64/dotnet7.0.8'.getBytes(), null))
1 * read(new JsonRpcRequest("eth_blockNumber", new ListParams())) >>
Mono.just(new JsonRpcResponse("\"0x10df3e5\"".getBytes(), null))
1 * read(new JsonRpcRequest("eth_getBalance", new ListParams(["0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", "0x10dccd5"]))) >>
1 * read(new ChainRequest("web3_clientVersion", new ListParams())) >>
Mono.just(new ChainResponse('no/v1.19.3+e8ac1da4/linux-x64/dotnet7.0.8'.getBytes(), null))
1 * read(new ChainRequest("eth_blockNumber", new ListParams())) >>
Mono.just(new ChainResponse("\"0x10df3e5\"".getBytes(), null))
1 * read(new ChainRequest("eth_getBalance", new ListParams(["0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", "0x10dccd5"]))) >>
Mono.error(new RuntimeException())
1 * read(new JsonRpcRequest("eth_getBalance", new ListParams(["0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", "0x2710"]))) >>
Mono.just(new JsonRpcResponse("".getBytes(), null))
1 * read(new ChainRequest("eth_getBalance", new ListParams(["0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", "0x2710"]))) >>
Mono.just(new ChainResponse("".getBytes(), null))
}
}
def detector = new EthereumLabelsDetector(up.getIngressReader(), Chain.ETHEREUM__MAINNET)

View File

@@ -9,7 +9,7 @@ import io.emeraldpay.dshackle.test.TestingCommons
import io.emeraldpay.dshackle.upstream.EmptyHead
import io.emeraldpay.dshackle.upstream.Head
import io.emeraldpay.dshackle.upstream.calls.DefaultEthereumMethods
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import io.emeraldpay.dshackle.upstream.ethereum.json.BlockJson
import org.apache.commons.collections4.functors.ConstantFactory
@@ -35,7 +35,7 @@ class EthereumLocalReaderSpec extends Specification {
null
)
when:
def act = router.read(new JsonRpcRequest("eth_coinbase", new ListParams())).block(Duration.ofSeconds(1))
def act = router.read(new ChainRequest("eth_coinbase", new ListParams())).block(Duration.ofSeconds(1))
then:
act.resultAsProcessedString == "0x0000000000000000000000000000000000000000"
}
@@ -55,7 +55,7 @@ class EthereumLocalReaderSpec extends Specification {
null
)
when:
def act = router.read(new JsonRpcRequest("eth_getTransactionByHash", new ListParams(["test"]), 10))
def act = router.read(new ChainRequest("eth_getTransactionByHash", new ListParams(["test"]), 10))
.block(Duration.ofSeconds(1))
then:
act == null

View File

@@ -21,9 +21,9 @@ import io.emeraldpay.dshackle.reader.Reader
import io.emeraldpay.dshackle.test.ApiReaderMock
import io.emeraldpay.dshackle.test.TestingCommons
import io.emeraldpay.dshackle.upstream.Head
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcError
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainCallError
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import io.emeraldpay.dshackle.upstream.Upstream
import io.emeraldpay.dshackle.upstream.ethereum.domain.Address
@@ -108,8 +108,8 @@ class EthereumUpstreamValidatorSpec extends Specification {
def up = Mock(Upstream) {
2 * getIngressReader() >> Mock(Reader) { reader ->
2 * reader.read(_) >>> [
Mono.just(new JsonRpcResponse('true'.getBytes(), null)),
Mono.just(new JsonRpcResponse('false'.getBytes(), null))
Mono.just(new ChainResponse('true'.getBytes(), null)),
Mono.just(new ChainResponse('false'.getBytes(), null))
]
}
2 * getHead() >> Mock(Head) {head ->
@@ -280,9 +280,9 @@ class EthereumUpstreamValidatorSpec extends Specification {
def up = Mock(Upstream) {
2 * getIngressReader() >>
Mock(Reader) {
1 * read(new JsonRpcRequest("eth_blockNumber", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
1 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
Mono.just(new JsonRpcResponse('"result"'.getBytes(), null))
1 * read(new ChainRequest("eth_blockNumber", new ListParams())) >> Mono.just(new ChainResponse('"0x10ff9be"'.getBytes(), null))
1 * read(new ChainRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
Mono.just(new ChainResponse('"result"'.getBytes(), null))
}
}
def validator = new EthereumUpstreamValidator(ETHEREUM__MAINNET, up, options, conf)
@@ -300,13 +300,13 @@ class EthereumUpstreamValidatorSpec extends Specification {
}.buildOptions()
def up = Mock(Upstream) {
3 * getIngressReader() >> Mock(Reader) {
1 * read(new JsonRpcRequest("eth_call", new ListParams([new TransactionCallJson(
1 * read(new ChainRequest("eth_call", new ListParams([new TransactionCallJson(
Address.from("0x32268860cAAc2948Ab5DdC7b20db5a420467Cf96"),
HexData.from("0xd8a26e3a00000000000000000000000000000000000000000000000000000000000f4240")
), "latest"]))) >> Mono.just(new JsonRpcResponse("0x00000000000000000000".getBytes(), null))
1 * read(new JsonRpcRequest("eth_blockNumber", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
1 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
Mono.just(new JsonRpcResponse('"result"'.getBytes(), null))
), "latest"]))) >> Mono.just(new ChainResponse("0x00000000000000000000".getBytes(), null))
1 * read(new ChainRequest("eth_blockNumber", new ListParams())) >> Mono.just(new ChainResponse('"0x10ff9be"'.getBytes(), null))
1 * read(new ChainRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
Mono.just(new ChainResponse('"result"'.getBytes(), null))
}
}
def validator = new EthereumUpstreamValidator(ETHEREUM__MAINNET, up, options, conf)
@@ -324,13 +324,13 @@ class EthereumUpstreamValidatorSpec extends Specification {
}.buildOptions()
def up = Mock(Upstream) {
3 * getIngressReader() >> Mock(Reader) {
1 * read(new JsonRpcRequest("eth_call", new ListParams([new TransactionCallJson(
1 * read(new ChainRequest("eth_call", new ListParams([new TransactionCallJson(
Address.from("0x32268860cAAc2948Ab5DdC7b20db5a420467Cf96"),
HexData.from("0xd8a26e3a00000000000000000000000000000000000000000000000000000000000f4240")
), "latest"]))) >> Mono.just(new JsonRpcResponse(null, new JsonRpcError(1, "Too long")))
1 * read(new JsonRpcRequest("eth_blockNumber", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
1 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
Mono.just(new JsonRpcResponse('"result"'.getBytes(), null))
), "latest"]))) >> Mono.just(new ChainResponse(null, new ChainCallError(1, "Too long")))
1 * read(new ChainRequest("eth_blockNumber", new ListParams())) >> Mono.just(new ChainResponse('"0x10ff9be"'.getBytes(), null))
1 * read(new ChainRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
Mono.just(new ChainResponse('"result"'.getBytes(), null))
}
}
def validator = new EthereumUpstreamValidator(ETHEREUM__MAINNET, up, options, conf)
@@ -348,11 +348,11 @@ class EthereumUpstreamValidatorSpec extends Specification {
}.buildOptions()
def up = Mock(Upstream) {
4 * getIngressReader() >> Mock(Reader) {
1 * read(new JsonRpcRequest("eth_chainId", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x1"'.getBytes(), null))
1 * read(new JsonRpcRequest("net_version", new ListParams())) >> Mono.just(new JsonRpcResponse('"1"'.getBytes(), null))
1 * read(new JsonRpcRequest("eth_blockNumber", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
1 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
Mono.just(new JsonRpcResponse('"result"'.getBytes(), null))
1 * read(new ChainRequest("eth_chainId", new ListParams())) >> Mono.just(new ChainResponse('"0x1"'.getBytes(), null))
1 * read(new ChainRequest("net_version", new ListParams())) >> Mono.just(new ChainResponse('"1"'.getBytes(), null))
1 * read(new ChainRequest("eth_blockNumber", new ListParams())) >> Mono.just(new ChainResponse('"0x10ff9be"'.getBytes(), null))
1 * read(new ChainRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
Mono.just(new ChainResponse('"result"'.getBytes(), null))
}
}
def validator = new EthereumUpstreamValidator(ETHEREUM__MAINNET, up, options, conf)
@@ -370,11 +370,11 @@ class EthereumUpstreamValidatorSpec extends Specification {
}.buildOptions()
def up = Mock(Upstream) {
4 * getIngressReader() >> Mock(Reader) {
1 * read(new JsonRpcRequest("eth_chainId", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x1"'.getBytes(), null))
1 * read(new JsonRpcRequest("net_version", new ListParams())) >> Mono.just(new JsonRpcResponse('"1"'.getBytes(), null))
1 * read(new JsonRpcRequest("eth_blockNumber", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
1 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
Mono.just(new JsonRpcResponse('"result"'.getBytes(), null))
1 * read(new ChainRequest("eth_chainId", new ListParams())) >> Mono.just(new ChainResponse('"0x1"'.getBytes(), null))
1 * read(new ChainRequest("net_version", new ListParams())) >> Mono.just(new ChainResponse('"1"'.getBytes(), null))
1 * read(new ChainRequest("eth_blockNumber", new ListParams())) >> Mono.just(new ChainResponse('"0x10ff9be"'.getBytes(), null))
1 * read(new ChainRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
Mono.just(new ChainResponse('"result"'.getBytes(), null))
}
}
def validator = new EthereumUpstreamValidator(OPTIMISM__MAINNET, up, options, conf)
@@ -390,15 +390,15 @@ class EthereumUpstreamValidatorSpec extends Specification {
def options = ChainOptions.PartialOptions.getDefaults().buildOptions()
def up = Mock(Upstream) {
5 * getIngressReader() >> Mock(Reader) {
1 * read(new JsonRpcRequest("eth_chainId", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x1"'.getBytes(), null))
1 * read(new JsonRpcRequest("net_version", new ListParams())) >> Mono.just(new JsonRpcResponse('"1"'.getBytes(), null))
1 * read(new JsonRpcRequest("eth_call", new ListParams([new TransactionCallJson(
1 * read(new ChainRequest("eth_chainId", new ListParams())) >> Mono.just(new ChainResponse('"0x1"'.getBytes(), null))
1 * read(new ChainRequest("net_version", new ListParams())) >> Mono.just(new ChainResponse('"1"'.getBytes(), null))
1 * read(new ChainRequest("eth_call", new ListParams([new TransactionCallJson(
Address.from("0x32268860cAAc2948Ab5DdC7b20db5a420467Cf96"),
HexData.from("0xd8a26e3a00000000000000000000000000000000000000000000000000000000000f4240")
), "latest"]))) >> Mono.just(new JsonRpcResponse("0x00000000000000000000".getBytes(), null))
1 * read(new JsonRpcRequest("eth_blockNumber", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
1 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
Mono.just(new JsonRpcResponse('"result"'.getBytes(), null))
), "latest"]))) >> Mono.just(new ChainResponse("0x00000000000000000000".getBytes(), null))
1 * read(new ChainRequest("eth_blockNumber", new ListParams())) >> Mono.just(new ChainResponse('"0x10ff9be"'.getBytes(), null))
1 * read(new ChainRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
Mono.just(new ChainResponse('"result"'.getBytes(), null))
}
}
def validator = new EthereumUpstreamValidator(ETHEREUM__MAINNET, up, options, conf)
@@ -414,15 +414,15 @@ class EthereumUpstreamValidatorSpec extends Specification {
def options = ChainOptions.PartialOptions.getDefaults().buildOptions()
def up = Mock(Upstream) {
5 * getIngressReader() >> Mock(Reader) {
1 * read(new JsonRpcRequest("eth_chainId", new ListParams())) >> Mono.just(new JsonRpcResponse(null, new JsonRpcError(1, "Too long")))
1 * read(new JsonRpcRequest("net_version", new ListParams())) >> Mono.just(new JsonRpcResponse(null, new JsonRpcError(1, "Too long")))
1 * read(new JsonRpcRequest("eth_call", new ListParams([new TransactionCallJson(
1 * read(new ChainRequest("eth_chainId", new ListParams())) >> Mono.just(new ChainResponse(null, new ChainCallError(1, "Too long")))
1 * read(new ChainRequest("net_version", new ListParams())) >> Mono.just(new ChainResponse(null, new ChainCallError(1, "Too long")))
1 * read(new ChainRequest("eth_call", new ListParams([new TransactionCallJson(
Address.from("0x32268860cAAc2948Ab5DdC7b20db5a420467Cf96"),
HexData.from("0xd8a26e3a00000000000000000000000000000000000000000000000000000000000f4240")
), "latest"]))) >> Mono.just(new JsonRpcResponse(null, new JsonRpcError(1, "Too long")))
1 * read(new JsonRpcRequest("eth_blockNumber", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
1 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
Mono.just(new JsonRpcResponse('"result"'.getBytes(), null))
), "latest"]))) >> Mono.just(new ChainResponse(null, new ChainCallError(1, "Too long")))
1 * read(new ChainRequest("eth_blockNumber", new ListParams())) >> Mono.just(new ChainResponse('"0x10ff9be"'.getBytes(), null))
1 * read(new ChainRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
Mono.just(new ChainResponse('"result"'.getBytes(), null))
}
}
def validator = new EthereumUpstreamValidator(ETHEREUM__MAINNET, up, options, conf)

View File

@@ -25,8 +25,8 @@ import io.emeraldpay.dshackle.upstream.BlockValidator
import io.emeraldpay.dshackle.upstream.DefaultUpstream
import io.emeraldpay.dshackle.upstream.ethereum.json.BlockJson
import io.emeraldpay.dshackle.upstream.forkchoice.AlwaysForkChoice
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import io.emeraldpay.dshackle.upstream.ethereum.domain.BlockHash
import io.emeraldpay.dshackle.upstream.ethereum.json.TransactionRefJson
@@ -62,7 +62,7 @@ class GenericWsHeadSpec extends Specification {
}
def reader = Mock(Reader) {
1 * it.read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams("latest", false))) >> Mono.empty()
1 * it.read(new ChainRequest("eth_getBlockByNumber", new ListParams("latest", false))) >> Mono.empty()
}
def ws = Mock(WsSubscriptions) {
@@ -339,7 +339,7 @@ class GenericWsHeadSpec extends Specification {
block.totalDifficulty = BigInteger.ONE
def reader = Mock(Reader) {
1 * it.read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams("latest", false))) >> Mono.empty()
1 * it.read(new ChainRequest("eth_getBlockByNumber", new ListParams("latest", false))) >> Mono.empty()
}
def subId = "subId"
def ws = Mock(WsSubscriptions) {
@@ -347,8 +347,8 @@ class GenericWsHeadSpec extends Specification {
1 * it.subscribe(_) >> new WsSubscriptions.SubscribeData(
Flux.error(new RuntimeException()), "id", new AtomicReference<String>(subId)
)
1 * it.unsubscribe(new JsonRpcRequest("eth_unsubscribe", new ListParams(subId), 2, null, null, false)) >>
Mono.just(new JsonRpcResponse("".bytes, null))
1 * it.unsubscribe(new ChainRequest("eth_unsubscribe", new ListParams(subId), 2, null, null, false)) >>
Mono.just(new ChainResponse("".bytes, null))
}
def head = new GenericWsHead(new AlwaysForkChoice(), BlockValidator.ALWAYS_VALID, reader, ws, Schedulers.boundedElastic(), Schedulers.boundedElastic(), upstream, EthereumChainSpecific.INSTANCE)

View File

@@ -5,7 +5,7 @@ import io.emeraldpay.dshackle.test.GenericUpstreamMock
import io.emeraldpay.dshackle.test.MockWSServer
import io.emeraldpay.dshackle.test.TestingCommons
import io.emeraldpay.dshackle.upstream.DefaultUpstream
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import reactor.core.scheduler.Schedulers
import reactor.test.StepVerifier
@@ -56,7 +56,7 @@ class WsConnectionImplRealSpec extends Specification {
def "Can make a RPC request"() {
when:
conn.connect()
def resp = conn.callRpc(new JsonRpcRequest("foo_bar", new ListParams()))
def resp = conn.callRpc(new ChainRequest("foo_bar", new ListParams()))
then:
StepVerifier.create(resp)
.then {
@@ -88,7 +88,7 @@ class WsConnectionImplRealSpec extends Specification {
server.onNextReply('{"jsonrpc":"2.0","id":100,"result":1}')
// reconnects in 2 seconds, give 1 extra
Thread.sleep(3_000)
def resp = conn.callRpc(new JsonRpcRequest("foo_bar", new ListParams())).block(Duration.ofSeconds(1))
def resp = conn.callRpc(new ChainRequest("foo_bar", new ListParams())).block(Duration.ofSeconds(1))
def act = server.received
then:
@@ -101,7 +101,7 @@ class WsConnectionImplRealSpec extends Specification {
conn.connect()
conn.reconnectIntervalSeconds = 2
def resp = conn.callRpc(new JsonRpcRequest("foo_bar", new ListParams()))
def resp = conn.callRpc(new ChainRequest("foo_bar", new ListParams()))
then:
StepVerifier.create(resp)
@@ -122,7 +122,7 @@ class WsConnectionImplRealSpec extends Specification {
server.onNextReply('{"jsonrpc":"2.0","id":100,"result":1}')
Thread.sleep(3_000)
def resp = conn.callRpc(new JsonRpcRequest("foo_bar", new ListParams())).block(Duration.ofSeconds(1))
def resp = conn.callRpc(new ChainRequest("foo_bar", new ListParams())).block(Duration.ofSeconds(1))
def act = server.received
then:
act.size() == 1
@@ -141,7 +141,7 @@ class WsConnectionImplRealSpec extends Specification {
// reconnects in 2 seconds, give 1 extra
Thread.sleep(3_000)
def resp = conn.callRpc(new JsonRpcRequest("foo_bar", new ListParams()))
def resp = conn.callRpc(new ChainRequest("foo_bar", new ListParams()))
then:
StepVerifier.create(resp)
.then {

View File

@@ -20,7 +20,7 @@ import io.emeraldpay.dshackle.Global
import io.emeraldpay.dshackle.test.GenericUpstreamMock
import io.emeraldpay.dshackle.test.TestingCommons
import io.emeraldpay.dshackle.upstream.DefaultUpstream
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import io.emeraldpay.dshackle.upstream.ethereum.domain.TransactionId
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcResponseError
@@ -59,7 +59,7 @@ class WsConnectionImplSpec extends Specification {
when:
Flux.from(ws.handle(wsApiMock.inbound, wsApiMock.outbound)).subscribe()
def act = ws.callRpc(new JsonRpcRequest("eth_getTransactionByHash", new ListParams(["0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200"]), 15, null, null, false))
def act = ws.callRpc(new ChainRequest("eth_getTransactionByHash", new ListParams(["0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200"]), 15, null, null, false))
then:
StepVerifier.create(act)
@@ -91,7 +91,7 @@ class WsConnectionImplSpec extends Specification {
when:
Flux.from(ws.handle(wsApiMock.inbound, wsApiMock.outbound)).subscribe()
def act = ws.callRpc(new JsonRpcRequest("eth_getTransactionByHash", new ListParams(["0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200"]), 15, null, null, false))
def act = ws.callRpc(new ChainRequest("eth_getTransactionByHash", new ListParams(["0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200"]), 15, null, null, false))
then:
StepVerifier.create(act)
@@ -125,7 +125,7 @@ class WsConnectionImplSpec extends Specification {
when:
Flux.from(ws.handle(wsApiMock.inbound, wsApiMock.outbound)).subscribe()
def act = ws.callRpc(new JsonRpcRequest("eth_getTransactionByHash", new ListParams(["0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200"]), 15, null, null, false))
def act = ws.callRpc(new ChainRequest("eth_getTransactionByHash", new ListParams(["0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200"]), 15, null, null, false))
then:
StepVerifier.create(act)

View File

@@ -15,8 +15,8 @@
*/
package io.emeraldpay.dshackle.upstream.ethereum
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcWsMessage
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import reactor.core.publisher.Flux
@@ -46,7 +46,7 @@ class WsSubscriptionsImplSpec extends Specification {
def ws = new WsSubscriptionsImpl(pool)
when:
def act = ws.subscribe(new JsonRpcRequest("eth_subscribe", new ListParams(["foo_bar"])))
def act = ws.subscribe(new ChainRequest("eth_subscribe", new ListParams(["foo_bar"])))
.data
.map { new String(it) }
.take(3)
@@ -55,9 +55,9 @@ class WsSubscriptionsImplSpec extends Specification {
then:
act == ["100", "101", "102"]
1 * conn.callRpc({ JsonRpcRequest req ->
1 * conn.callRpc({ ChainRequest req ->
req.method == "eth_subscribe" && req.params == new ListParams(["foo_bar"])
}) >> Mono.just(new JsonRpcResponse('"0xcff45d00e7"'.bytes, null))
}) >> Mono.just(new ChainResponse('"0xcff45d00e7"'.bytes, null))
1 * conn.getSubscribeResponses() >> answers
}
@@ -84,7 +84,7 @@ class WsSubscriptionsImplSpec extends Specification {
def ws = new WsSubscriptionsImpl(pool)
when:
def act = ws.subscribe(new JsonRpcRequest("eth_subscribe", new ListParams(["foo_bar"])))
def act = ws.subscribe(new ChainRequest("eth_subscribe", new ListParams(["foo_bar"])))
.data
.map { new String(it) }
.take(3)
@@ -93,9 +93,9 @@ class WsSubscriptionsImplSpec extends Specification {
then:
act == ["100", "101", "102"]
1 * conn.callRpc({ JsonRpcRequest req ->
1 * conn.callRpc({ ChainRequest req ->
req.method == "eth_subscribe" && req.params == new ListParams(["foo_bar"])
}) >> Mono.just(new JsonRpcResponse('"0xcff45d00e7"'.bytes, null))
}) >> Mono.just(new ChainResponse('"0xcff45d00e7"'.bytes, null))
1 * conn.getSubscribeResponses() >> answers
}
}

View File

@@ -15,7 +15,7 @@
*/
package io.emeraldpay.dshackle.upstream.ethereum.subscribe
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import io.emeraldpay.dshackle.upstream.Selector
import io.emeraldpay.dshackle.upstream.ethereum.WsSubscriptions
@@ -43,7 +43,7 @@ class WebsocketPendingTxesSpec extends Specification {
.collectList().block(Duration.ofSeconds(1))
then:
1 * ws.subscribe(new JsonRpcRequest("eth_subscribe", new ListParams(["newPendingTransactions"]))) >> new WsSubscriptions.SubscribeData(
1 * ws.subscribe(new ChainRequest("eth_subscribe", new ListParams(["newPendingTransactions"]))) >> new WsSubscriptions.SubscribeData(
Flux.fromIterable(responses), "id", new AtomicReference<String>("")
)
txes.collect {it.toHex() } == [

View File

@@ -1,5 +1,6 @@
package io.emeraldpay.dshackle.upstream.rpcclient
import io.emeraldpay.dshackle.upstream.ChainCallError
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcException
import nl.jqno.equalsverifier.EqualsVerifier
import spock.lang.Specification
@@ -8,7 +9,7 @@ class JsonRpcErrorSpec extends Specification {
def "Build from RpcException"() {
when:
def act = JsonRpcError.from(new RpcException(-32123, "test test"))
def act = ChainCallError.from(new RpcException(-32123, "test test"))
then:
act.code == -32123
act.message == "test test"
@@ -17,7 +18,7 @@ class JsonRpcErrorSpec extends Specification {
def "Build from RpcException with details"() {
when:
def act = JsonRpcError.from(new RpcException(-32123, "test test", "foo bar"))
def act = ChainCallError.from(new RpcException(-32123, "test test", "foo bar"))
then:
act.code == -32123
act.message == "test test"
@@ -26,7 +27,7 @@ class JsonRpcErrorSpec extends Specification {
def "Equals"() {
when:
def v = EqualsVerifier.forClass(JsonRpcError)
def v = EqualsVerifier.forClass(ChainCallError)
then:
v.verify()
}

View File

@@ -6,9 +6,9 @@ import io.emeraldpay.api.proto.BlockchainOuterClass
import io.emeraldpay.api.proto.Common
import io.emeraldpay.dshackle.Chain
import io.emeraldpay.dshackle.test.MockGrpcServer
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcException
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcResponseError
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import io.grpc.stub.StreamObserver
import spock.lang.Specification
@@ -40,7 +40,7 @@ class JsonRpcGrpcClientSpec extends Specification {
when:
def act = client.read(
new JsonRpcRequest("test", new ListParams())
new ChainRequest("test", new ListParams())
).block(Duration.ofSeconds(1))
then:
@@ -74,7 +74,7 @@ class JsonRpcGrpcClientSpec extends Specification {
when:
client.read(
new JsonRpcRequest("test", new ListParams())
new ChainRequest("test", new ListParams())
).block(Duration.ofSeconds(1))
then:

View File

@@ -17,8 +17,10 @@ package io.emeraldpay.dshackle.upstream.rpcclient
import io.emeraldpay.dshackle.test.TestingCommons
import io.emeraldpay.dshackle.upstream.ChainException
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.RequestMetrics
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcResponseError
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import io.micrometer.core.instrument.Counter
import io.micrometer.core.instrument.Timer
import org.mockserver.integration.ClientAndServer
@@ -29,11 +31,11 @@ import spock.lang.Specification
import java.time.Duration
class JsonRpcHttpClientSpec extends Specification {
class JsonRpcHttpReaderSpec extends Specification {
ClientAndServer mockServer
int port = 19332
RpcMetrics metrics = new RpcMetrics(
RequestMetrics metrics = new RequestMetrics(
Timer.builder("test1").register(TestingCommons.meterRegistry),
Counter.builder("test2").register(TestingCommons.meterRegistry)
)
@@ -49,7 +51,7 @@ class JsonRpcHttpClientSpec extends Specification {
def "Make a request"() {
setup:
JsonRpcHttpClient client = new JsonRpcHttpClient("localhost:${port}", metrics,null, null)
JsonRpcHttpReader client = new JsonRpcHttpReader("localhost:${port}", metrics,null, null)
def resp = '{' +
' "jsonrpc": "2.0",' +
' "result": "0x98de45",' +
@@ -62,7 +64,7 @@ class JsonRpcHttpClientSpec extends Specification {
HttpResponse.response(resp)
)
when:
def act = client.read(new JsonRpcRequest("test", new ListParams())).block()
def act = client.read(new ChainRequest("test", new ListParams())).block()
then:
act.error == null
new String(act.result) == '"0x98de45"'
@@ -70,7 +72,7 @@ class JsonRpcHttpClientSpec extends Specification {
def "Produces RPC Exception on error status code"() {
setup:
def client = new JsonRpcHttpClient("localhost:${port}", metrics, null, null)
def client = new JsonRpcHttpReader("localhost:${port}", metrics, null, null)
mockServer.when(
HttpRequest.request()
@@ -81,12 +83,12 @@ class JsonRpcHttpClientSpec extends Specification {
)
when:
def act = client.read(
new JsonRpcRequest("ping", new ListParams())
new ChainRequest("ping", new ListParams())
).block(Duration.ofSeconds(1))
then:
def t = thrown(RuntimeException) // reactor.core.Exceptions$ReactiveException
t.cause instanceof JsonRpcException
with(((JsonRpcException)t.cause).error) {
t.cause instanceof ChainException
with(((ChainException)t.cause).error) {
code == RpcResponseError.CODE_UPSTREAM_INVALID_RESPONSE
message == "HTTP Code: 500"
}
@@ -94,7 +96,7 @@ class JsonRpcHttpClientSpec extends Specification {
def "Tries to extract message if HTTP error if it still contains a JSON RPC message"() {
setup:
def client = new JsonRpcHttpClient("localhost:${port}", metrics, null, null)
def client = new JsonRpcHttpReader("localhost:${port}", metrics, null, null)
mockServer.when(
HttpRequest.request()
@@ -109,12 +111,12 @@ class JsonRpcHttpClientSpec extends Specification {
)
when:
def act = client.read(
new JsonRpcRequest("ping", new ListParams())
new ChainRequest("ping", new ListParams())
).block(Duration.ofSeconds(1))
then:
def t = thrown(RuntimeException) // reactor.core.Exceptions$ReactiveException
t.cause instanceof JsonRpcException
with(((JsonRpcException)t.cause).error) {
t.cause instanceof ChainException
with(((ChainException)t.cause).error) {
code == -32603
message == "Something happened"
}

View File

@@ -15,15 +15,14 @@
*/
package io.emeraldpay.dshackle.upstream.rpcclient
import io.emeraldpay.dshackle.upstream.ChainRequest
import spock.lang.Specification
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
class JsonRpcRequestSpec extends Specification {
def "Serialize empty params"() {
setup:
def req = new JsonRpcRequest("test_foo", new ListParams())
def req = new ChainRequest("test_foo", new ListParams())
when:
def act = req.toJson()
then:
@@ -32,7 +31,7 @@ class JsonRpcRequestSpec extends Specification {
def "Serialize single param"() {
setup:
def req = new JsonRpcRequest("test_foo", new ListParams(["0x0000"]))
def req = new ChainRequest("test_foo", new ListParams(["0x0000"]))
when:
def act = req.toJson()
then:
@@ -41,7 +40,7 @@ class JsonRpcRequestSpec extends Specification {
def "Serialize two params"() {
setup:
def req = new JsonRpcRequest("test_foo", new ListParams(["0x0000", false]))
def req = new ChainRequest("test_foo", new ListParams(["0x0000", false]))
when:
def act = req.toJson()
then:
@@ -50,8 +49,8 @@ class JsonRpcRequestSpec extends Specification {
def "Same requests are equal"() {
setup:
def req1 = new JsonRpcRequest("test_foo", new ListParams(["0x0000", false]))
def req2 = new JsonRpcRequest("test_foo", new ListParams(["0x0000", false]))
def req1 = new ChainRequest("test_foo", new ListParams(["0x0000", false]))
def req2 = new ChainRequest("test_foo", new ListParams(["0x0000", false]))
when:
def act = req1.equals(req2)
then:

View File

@@ -17,6 +17,8 @@ package io.emeraldpay.dshackle.upstream.rpcclient
import com.fasterxml.jackson.databind.ObjectMapper
import io.emeraldpay.dshackle.Global
import io.emeraldpay.dshackle.upstream.ChainCallError
import io.emeraldpay.dshackle.upstream.ChainResponse
import spock.lang.Specification
class JsonRpcResponseSpec extends Specification {
@@ -25,8 +27,8 @@ class JsonRpcResponseSpec extends Specification {
def "Same responses are equal"() {
setup:
def resp1 = new JsonRpcResponse("\"hello\"".bytes, null)
def resp2 = new JsonRpcResponse("\"hello\"".bytes, null)
def resp1 = new ChainResponse("\"hello\"".bytes, null)
def resp2 = new ChainResponse("\"hello\"".bytes, null)
when:
def act = resp1.equals(resp2)
then:
@@ -35,35 +37,35 @@ class JsonRpcResponseSpec extends Specification {
def "Extract processed string without quoted"() {
when:
def act = new JsonRpcResponse("\"hello\"".bytes, null).resultAsProcessedString
def act = new ChainResponse("\"hello\"".bytes, null).resultAsProcessedString
then:
act == "hello"
}
def "Extract raw string with quoted"() {
when:
def act = new JsonRpcResponse("\"hello\"".bytes, null).resultAsRawString
def act = new ChainResponse("\"hello\"".bytes, null).resultAsRawString
then:
act == "\"hello\""
}
def "Fails to extract processed string if not quoted"() {
when:
new JsonRpcResponse("{\"hello\": 1}".bytes, null).resultAsProcessedString
new ChainResponse("{\"hello\": 1}".bytes, null).resultAsProcessedString
then:
thrown(IllegalStateException)
}
def "Recognizes null"() {
when:
def act = new JsonRpcResponse("null".bytes, null)
def act = new ChainResponse("null".bytes, null)
then:
act.isNull()
}
def "Serialize int id and null result"() {
setup:
def json = new JsonRpcResponse("null".bytes, null, new JsonRpcResponse.NumberId(1), null, null, null)
def json = new ChainResponse("null".bytes, null, new ChainResponse.NumberId(1), null, null, null)
when:
def act = objectMapper.writeValueAsString(json)
then:
@@ -72,7 +74,7 @@ class JsonRpcResponseSpec extends Specification {
def "Serialize int id and string result"() {
setup:
def json = new JsonRpcResponse('"Hello World"'.bytes, null, new JsonRpcResponse.NumberId(10), null, null, null)
def json = new ChainResponse('"Hello World"'.bytes, null, new ChainResponse.NumberId(10), null, null, null)
when:
def act = objectMapper.writeValueAsString(json)
then:
@@ -81,7 +83,7 @@ class JsonRpcResponseSpec extends Specification {
def "Serialize int id and object result"() {
setup:
def json = new JsonRpcResponse('{"foo": "Hello World", "bar": 1}'.bytes, null, new JsonRpcResponse.NumberId(101), null, null, null)
def json = new ChainResponse('{"foo": "Hello World", "bar": 1}'.bytes, null, new ChainResponse.NumberId(101), null, null, null)
when:
def act = objectMapper.writeValueAsString(json)
then:
@@ -90,7 +92,7 @@ class JsonRpcResponseSpec extends Specification {
def "Serialize int id and error"() {
setup:
def json = new JsonRpcResponse(null, new JsonRpcError(-32041, "Oooops"), new JsonRpcResponse.NumberId(101), null, null, null)
def json = new ChainResponse(null, new ChainCallError(-32041, "Oooops"), new ChainResponse.NumberId(101), null, null, null)
when:
def act = objectMapper.writeValueAsString(json)
then:
@@ -99,7 +101,7 @@ class JsonRpcResponseSpec extends Specification {
def "Serialize string id and null result"() {
setup:
def json = new JsonRpcResponse("null".bytes, null, new JsonRpcResponse.StringId("asf01t1gg"), null, null, null)
def json = new ChainResponse("null".bytes, null, new ChainResponse.StringId("asf01t1gg"), null, null, null)
when:
def act = objectMapper.writeValueAsString(json)
then:
@@ -108,7 +110,7 @@ class JsonRpcResponseSpec extends Specification {
def "Serialize string id and string result"() {
setup:
def json = new JsonRpcResponse('"Hello World"'.bytes, null, new JsonRpcResponse.StringId("10"), null, null, null)
def json = new ChainResponse('"Hello World"'.bytes, null, new ChainResponse.StringId("10"), null, null, null)
when:
def act = objectMapper.writeValueAsString(json)
then:
@@ -117,7 +119,7 @@ class JsonRpcResponseSpec extends Specification {
def "Serialize string id and object result"() {
setup:
def json = new JsonRpcResponse('{"foo": "Hello World", "bar": 1}'.bytes, null, new JsonRpcResponse.StringId("g8gk19g"), null, null, null)
def json = new ChainResponse('{"foo": "Hello World", "bar": 1}'.bytes, null, new ChainResponse.StringId("g8gk19g"), null, null, null)
when:
def act = objectMapper.writeValueAsString(json)
then:
@@ -126,9 +128,9 @@ class JsonRpcResponseSpec extends Specification {
def "Serialize string id and error"() {
setup:
def json = new JsonRpcResponse(null,
new JsonRpcError(-32041, "Oooops"),
new JsonRpcResponse.StringId("9kbo29gkaasf"), null, null, null )
def json = new ChainResponse(null,
new ChainCallError(-32041, "Oooops"),
new ChainResponse.StringId("9kbo29gkaasf"), null, null, null )
when:
def act = objectMapper.writeValueAsString(json)
then:

View File

@@ -1,8 +1,9 @@
package io.emeraldpay.dshackle.upstream.rpcclient
import io.emeraldpay.dshackle.upstream.ChainException
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ethereum.WsConnection
import io.emeraldpay.dshackle.upstream.ethereum.WsConnectionPool
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import reactor.core.Exceptions
import spock.lang.Specification
@@ -18,11 +19,11 @@ class JsonRpcWsClientSpec extends Specification {
}
def client = new JsonRpcWsClient(pool)
when:
client.read(new JsonRpcRequest("foo_bar", new ListParams([]), 1))
client.read(new ChainRequest("foo_bar", new ListParams([]), 1))
.block(Duration.ofSeconds(1))
then:
def t = thrown(Exceptions.ReactiveException)
t.cause instanceof JsonRpcException
t.cause instanceof ChainException
1 * ws.isConnected() >> false
}
}

View File

@@ -11,15 +11,15 @@ import org.junit.jupiter.params.provider.MethodSource
import org.mockito.kotlin.mock
import org.springframework.cloud.sleuth.Tracer
class RpcReaderFactoryTest {
private val defaultFactory = RpcReaderFactory.Default()
class RequestReaderFactoryTest {
private val defaultFactory = RequestReaderFactory.Default()
@ParameterizedTest
@MethodSource("data")
fun `create BroadcastReader for MaximumValueQuorum and BroadcastQuorum`(
rpcReaderData: RpcReaderFactory.RpcReaderData,
readerData: RequestReaderFactory.ReaderData,
) {
val reader = defaultFactory.create(rpcReaderData)
val reader = defaultFactory.create(readerData)
assertTrue(reader is BroadcastReader)
}
@@ -32,9 +32,8 @@ class RpcReaderFactoryTest {
fun data(): List<Arguments> {
return listOf(
Arguments.of(
RpcReaderFactory.RpcReaderData(
RequestReaderFactory.ReaderData(
ms,
"method",
Selector.empty,
MaximumValueQuorum(),
null,
@@ -42,9 +41,8 @@ class RpcReaderFactoryTest {
),
),
Arguments.of(
RpcReaderFactory.RpcReaderData(
RequestReaderFactory.ReaderData(
ms,
"method",
Selector.empty,
BroadcastQuorum(),
null,

View File

@@ -5,8 +5,8 @@ import io.emeraldpay.api.proto.BlockchainOuterClass.NativeCallReplyItem
import io.emeraldpay.api.proto.BlockchainOuterClass.NativeCallRequest
import io.emeraldpay.dshackle.config.MainConfig
import io.emeraldpay.dshackle.upstream.MultistreamHolder
import io.emeraldpay.dshackle.upstream.rpcclient.stream.Chunk
import io.emeraldpay.dshackle.upstream.signature.ResponseSigner
import io.emeraldpay.dshackle.upstream.stream.Chunk
import org.junit.jupiter.api.Test
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock

View File

@@ -1,11 +1,9 @@
package io.emeraldpay.dshackle.upstream
import io.emeraldpay.dshackle.Chain
import io.emeraldpay.dshackle.reader.JsonRpcReader
import io.emeraldpay.dshackle.reader.ChainReader
import io.emeraldpay.dshackle.upstream.ethereum.EthereumLowerBoundBlockDetector
import io.emeraldpay.dshackle.upstream.polkadot.PolkadotLowerBoundBlockDetector
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.params.ParameterizedTest
@@ -23,7 +21,7 @@ class RecursiveLowerBoundBlockDetectorTest {
@ParameterizedTest
@MethodSource("detectors")
fun `find lower block closer to the height`(
reader: JsonRpcReader,
reader: ChainReader,
detectorClass: Class<LowerBoundBlockDetector>,
) {
val head = mock<Head> {
@@ -49,7 +47,7 @@ class RecursiveLowerBoundBlockDetectorTest {
@ParameterizedTest
@MethodSource("detectorsFirstBlock")
fun `lower block is 0x1`(
reader: JsonRpcReader,
reader: ChainReader,
detectorClass: Class<LowerBoundBlockDetector>,
) {
val head = mock<Head> {
@@ -84,15 +82,15 @@ class RecursiveLowerBoundBlockDetectorTest {
@JvmStatic
fun detectors(): List<Arguments> = listOf(
Arguments.of(
mock<JsonRpcReader> {
mock<ChainReader> {
blocks.forEach {
if (it == 17964844L) {
on {
read(JsonRpcRequest("eth_getBalance", ListParams("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", it.toHex())))
} doReturn Mono.just(JsonRpcResponse(ByteArray(0), null))
read(ChainRequest("eth_getBalance", ListParams("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", it.toHex())))
} doReturn Mono.just(ChainResponse(ByteArray(0), null))
} else {
on {
read(JsonRpcRequest("eth_getBalance", ListParams("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", it.toHex())))
read(ChainRequest("eth_getBalance", ListParams("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", it.toHex())))
} doReturn Mono.error(RuntimeException("missing trie node"))
}
}
@@ -100,21 +98,21 @@ class RecursiveLowerBoundBlockDetectorTest {
EthereumLowerBoundBlockDetector::class.java,
),
Arguments.of(
mock<JsonRpcReader> {
mock<ChainReader> {
blocks.forEach {
if (it == 17964844L) {
on {
read(JsonRpcRequest("chain_getBlockHash", ListParams(it.toHex())))
} doReturn Mono.just(JsonRpcResponse("\"$hash1\"".toByteArray(), null))
read(ChainRequest("chain_getBlockHash", ListParams(it.toHex())))
} doReturn Mono.just(ChainResponse("\"$hash1\"".toByteArray(), null))
on {
read(JsonRpcRequest("state_getMetadata", ListParams(hash1)))
} doReturn Mono.just(JsonRpcResponse(ByteArray(0), null))
read(ChainRequest("state_getMetadata", ListParams(hash1)))
} doReturn Mono.just(ChainResponse(ByteArray(0), null))
} else {
on {
read(JsonRpcRequest("chain_getBlockHash", ListParams(it.toHex())))
} doReturn Mono.just(JsonRpcResponse("\"$hash2\"".toByteArray(), null))
read(ChainRequest("chain_getBlockHash", ListParams(it.toHex())))
} doReturn Mono.just(ChainResponse("\"$hash2\"".toByteArray(), null))
on {
read(JsonRpcRequest("state_getMetadata", ListParams(hash2)))
read(ChainRequest("state_getMetadata", ListParams(hash2)))
} doReturn Mono.error(RuntimeException("State already discarded for"))
}
}
@@ -126,16 +124,16 @@ class RecursiveLowerBoundBlockDetectorTest {
@JvmStatic
fun detectorsFirstBlock(): List<Arguments> = listOf(
Arguments.of(
mock<JsonRpcReader> {
mock<ChainReader> {
on {
read(any())
} doReturn Mono.just(JsonRpcResponse("\"0x1\"".toByteArray(), null))
} doReturn Mono.just(ChainResponse("\"0x1\"".toByteArray(), null))
},
PolkadotLowerBoundBlockDetector::class.java,
),
Arguments.of(
mock<JsonRpcReader> {
on { read(any()) } doReturn Mono.just(JsonRpcResponse(ByteArray(0), null))
mock<ChainReader> {
on { read(any()) } doReturn Mono.just(ChainResponse(ByteArray(0), null))
},
EthereumLowerBoundBlockDetector::class.java,
),

View File

@@ -0,0 +1,50 @@
package io.emeraldpay.dshackle.upstream.beaconchain
import io.emeraldpay.dshackle.data.BlockContainer
import io.emeraldpay.dshackle.data.BlockId
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import java.math.BigInteger
import java.time.Instant
class BeaconChainSpecificTest {
@Test
fun `test getting latest block`() {
val header = """
{
"execution_optimistic": false,
"finalized": false,
"data": {
"header": {
"message": {
"slot": "8639623",
"proposer_index": "830020",
"parent_root": "0x3306b3f2d5f4de709a9b13c51ca7bbeab41ee93f44c6873baf6a59495620dbbf",
"state_root": "0x1445392736bd2485e5afaaea62a642bea69f75379653e7a1f0846806af8d6d75",
"body_root": "0x0a02f2980fda874a050fc2f6fde63ebbeb749318f23325673f1fc4af2b252e84"
},
"signature": "0x961b9c71530f2a55630e3c943aa054f6a863c86fd53b6644c1680bdb2d70a65a0082e5282fb3bf54a0167ba706fe78961289a652da13594a00d63c4ef8d60f53f515ce5ca1ced41b25a7689fd6e6773ec6b771e4e1f67c37eea2b8ef26c5eb4f"
},
"root": "0x3ae4855df015bf9906f59aa0c612396105fa7c11495b5596fa946672c3ce5674",
"canonical": true
}
}
""".trimIndent().toByteArray()
val expected = BlockContainer(
height = 8639623,
hash = BlockId.from("0x3ae4855df015bf9906f59aa0c612396105fa7c11495b5596fa946672c3ce5674"),
difficulty = BigInteger.ZERO,
timestamp = Instant.EPOCH,
full = false,
json = header,
transactions = emptyList(),
upstreamId = "upId",
parentHash = BlockId.from("0x3306b3f2d5f4de709a9b13c51ca7bbeab41ee93f44c6873baf6a59495620dbbf"),
parsed = null,
)
val block = BeaconChainSpecific.parseBlock(header, "upId")
assertEquals(expected, block)
}
}

View File

@@ -0,0 +1,98 @@
package io.emeraldpay.dshackle.upstream.beaconchain
import io.emeraldpay.dshackle.foundation.ChainOptions
import io.emeraldpay.dshackle.reader.ChainReader
import io.emeraldpay.dshackle.upstream.ChainCallError
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.Head
import io.emeraldpay.dshackle.upstream.Upstream
import io.emeraldpay.dshackle.upstream.UpstreamAvailability
import io.emeraldpay.dshackle.upstream.rpcclient.RestParams
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.MethodSource
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import reactor.core.publisher.Mono
class BeaconChainValidatorTest {
@ParameterizedTest
@MethodSource("data")
fun `validation beacon chain`(
respHealth: Mono<ChainResponse>,
respSync: Mono<ChainResponse>,
respPeers: Mono<ChainResponse>,
expected: UpstreamAvailability,
) {
val reader = mock<ChainReader> {
on { read(ChainRequest("GET#/eth/v1/node/health", RestParams.emptyParams())) } doReturn
respHealth
on { read(ChainRequest("GET#/eth/v1/node/syncing", RestParams.emptyParams())) } doReturn
respSync
on { read(ChainRequest("GET#/eth/v1/node/peer_count", RestParams.emptyParams())) } doReturn
respPeers
}
val upstream = mock<Upstream> {
on { getIngressReader() } doReturn reader
on { getHead() } doReturn mock<Head>()
}
val validator = BeaconChainValidator(upstream, ChainOptions.PartialOptions.getDefaults().buildOptions())
val result = validator.validate().block()
assertEquals(expected, result)
}
companion object {
@JvmStatic
fun data(): List<Arguments> {
return listOf(
Arguments.of(
Mono.just(ChainResponse(ByteArray(0), null)),
Mono.just(ChainResponse("""{"data": {"is_syncing": false}}""".toByteArray(), null)),
Mono.just(ChainResponse("""{"data": {"connected": "20"}}""".toByteArray(), null)),
UpstreamAvailability.OK,
),
Arguments.of(
Mono.error<ChainResponse>(RuntimeException("error")),
Mono.just(ChainResponse("""{"data": {"is_syncing": false}}""".toByteArray(), null)),
Mono.just(ChainResponse("""{"data": {"connected": "20"}}""".toByteArray(), null)),
UpstreamAvailability.UNAVAILABLE,
),
Arguments.of(
Mono.just(ChainResponse(ByteArray(0), null)),
Mono.just(ChainResponse("""{"data": {"is_syncing": true}}""".toByteArray(), null)),
Mono.just(ChainResponse("""{"data": {"connected": "20"}}""".toByteArray(), null)),
UpstreamAvailability.SYNCING,
),
Arguments.of(
Mono.just(ChainResponse(ByteArray(0), null)),
Mono.just(ChainResponse("""{"data": {"is_syncing": false}}""".toByteArray(), null)),
Mono.just(ChainResponse("""{"data": {"connected": "0"}}""".toByteArray(), null)),
UpstreamAvailability.IMMATURE,
),
Arguments.of(
Mono.just(ChainResponse(ByteArray(0), null)),
Mono.error<ChainResponse>(RuntimeException("error")),
Mono.just(ChainResponse("""{"data": {"connected": "20"}}""".toByteArray(), null)),
UpstreamAvailability.UNAVAILABLE,
),
Arguments.of(
Mono.just(ChainResponse(ByteArray(0), null)),
Mono.just(ChainResponse("""{"data": {"is_syncing": false}}""".toByteArray(), null)),
Mono.error<ChainResponse>(RuntimeException("error")),
UpstreamAvailability.UNAVAILABLE,
),
Arguments.of(
Mono.just(ChainResponse(null, ChainCallError(1, "Error"))),
Mono.just(ChainResponse("""{"data": {"is_syncing": false}}""".toByteArray(), null)),
Mono.just(ChainResponse("""{"data": {"connected": "20"}}""".toByteArray(), null)),
UpstreamAvailability.UNAVAILABLE,
),
)
}
}
}

View File

@@ -42,7 +42,7 @@ class GenericConnectorFactoryCreatorTest {
mockConstruction(GenericRpcHead::class.java) { _, ctx -> args = ctx.arguments() }
.use {
factory.createConnectorFactoryCreator(
factory.createConnectorFactory(
"id",
UpstreamsConfig.RpcConnection(
UpstreamsConfig.HttpEndpoint(URI("http://localhost")),

View File

@@ -0,0 +1,50 @@
package io.emeraldpay.dshackle.upstream.restclient
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.MethodSource
class RestRequestParserTest {
@Test
fun `transform query params into string`() {
val queryParams = mapOf(
"first" to "coolParam",
"second" to "moreCoolParam",
)
val result = RestRequestParser.transformQueryParams(queryParams)
assertEquals("?first=coolParam&second=moreCoolParam", result)
}
@Test
fun `transform query params into empty string`() {
val result = RestRequestParser.transformQueryParams(emptyMap())
assertEquals("", result)
}
@ParameterizedTest
@MethodSource("data")
fun `transform path params into path with these params`(path: String, params: List<String>, expected: String) {
val result = RestRequestParser.transformPathParams(path, params)
assertEquals(expected, result)
}
companion object {
@JvmStatic
fun data(): List<Arguments> {
return listOf(
Arguments.of("/eth/v1/blocks/*/state/*/root", listOf("123", "678"), "/eth/v1/blocks/123/state/678/root"),
Arguments.of("/eth/v1/blocks/*/state/*", listOf("123", "678"), "/eth/v1/blocks/123/state/678"),
Arguments.of("/eth/v1/blocks", emptyList<String>(), "/eth/v1/blocks"),
Arguments.of("/eth/v1/blocks/*", listOf("123", "678"), "/eth/v1/blocks/123"),
Arguments.of("/eth/v1/blocks", listOf("123", "678"), "/eth/v1/blocks"),
)
}
}
}

View File

@@ -1,5 +1,9 @@
package io.emeraldpay.dshackle.upstream.rpcclient.stream
import io.emeraldpay.dshackle.upstream.stream.AggregateResponse
import io.emeraldpay.dshackle.upstream.stream.Chunk
import io.emeraldpay.dshackle.upstream.stream.SingleResponse
import io.emeraldpay.dshackle.upstream.stream.StreamResponse
import org.junit.jupiter.api.Assertions.assertArrayEquals
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNotNull

View File

@@ -2,10 +2,10 @@ package io.emeraldpay.dshackle.upstream.solana
import io.emeraldpay.dshackle.Chain
import io.emeraldpay.dshackle.Global
import io.emeraldpay.dshackle.reader.JsonRpcReader
import io.emeraldpay.dshackle.reader.ChainReader
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.Upstream
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
@@ -19,12 +19,12 @@ class SolanaLowerBoundBlockDetectorTest {
@Test
fun `get solana lower block and slot`() {
val reader = mock<JsonRpcReader> {
on { read(JsonRpcRequest("getFirstAvailableBlock", ListParams())) } doReturn
Mono.just(JsonRpcResponse("25000000".toByteArray(), null))
val reader = mock<ChainReader> {
on { read(ChainRequest("getFirstAvailableBlock", ListParams())) } doReturn
Mono.just(ChainResponse("25000000".toByteArray(), null))
on {
read(
JsonRpcRequest(
ChainRequest(
"getBlock",
ListParams(
25000000L,
@@ -37,7 +37,7 @@ class SolanaLowerBoundBlockDetectorTest {
),
)
} doReturn Mono.just(
JsonRpcResponse(
ChainResponse(
Global.objectMapper.writeValueAsBytes(
mapOf(
"blockHeight" to 21000000,