extract ethereum connectors from ethereum upstreams and add ethereum pos config

This commit is contained in:
terminal
2022-07-15 18:31:19 +04:00
parent 3d44b99346
commit 92218623f2
22 changed files with 688 additions and 464 deletions

View File

@@ -154,6 +154,26 @@ class UpstreamsConfigReaderSpec extends Specification {
}
}
def "Parse ethereum pos upstreams"() {
setup:
def config = this.class.getClassLoader().getResourceAsStream("upstreams-ethereum-pos.yaml")
when:
def act = reader.read(config)
then:
act != null
act.upstreams.size() == 1
with(act.upstreams.get(0)) {
id == "eth2-1"
chain == "ropsten"
connection instanceof UpstreamsConfig.EthereumPosConnection
with((UpstreamsConfig.EthereumPosConnection) connection) {
execution.rpc != null
execution.rpc.url == new URI("http://34.106.60.110:8545")
blockPriority == 100
}
}
}
def "Parse bitcoin upstreams with esplora"() {
setup:
def config = this.class.getClassLoader().getResourceAsStream("upstreams-bitcoin-esplora.yaml")

View File

@@ -87,7 +87,9 @@ class StreamHeadSpec extends Specification {
)
then:
StepVerifier.create(flux.take(2))
.then { upstream.nextBlock(BlockContainer.from(blocks[0])) }
.then {
upstream.nextBlock(BlockContainer.from(blocks[0]))
}
.expectNext(heads[0])
.then { upstream.nextBlock(BlockContainer.from(blocks[1])) }
.expectNext(heads[1])

View File

@@ -0,0 +1,29 @@
package io.emeraldpay.dshackle.test
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.ethereum.connectors.ConnectorFactory
import io.emeraldpay.dshackle.upstream.ethereum.connectors.EthereumConnector
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.grpc.Chain
class ConnectorFactoryMock implements ConnectorFactory {
Reader<JsonRpcRequest, JsonRpcResponse> api
Head head
ConnectorFactoryMock(Reader<JsonRpcRequest, JsonRpcResponse> api, Head head) {
this.api = api
this.head = head
}
boolean isValid() {
return true
}
EthereumConnector create(DefaultUpstream upstream, EthereumUpstreamValidator validator, Chain chain) {
return new EthereumConnectorMock(api, head)
}
}

View File

@@ -0,0 +1,37 @@
package io.emeraldpay.dshackle.test
import io.emeraldpay.dshackle.reader.Reader
import io.emeraldpay.dshackle.upstream.Head
import io.emeraldpay.dshackle.upstream.ethereum.connectors.EthereumConnector
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
class EthereumConnectorMock implements EthereumConnector {
Reader<JsonRpcRequest, JsonRpcResponse> api
Head head
EthereumConnectorMock(Reader<JsonRpcRequest, JsonRpcResponse> api, Head head) {
this.api = api
this.head = head
}
@Override
Reader<JsonRpcRequest, JsonRpcResponse> getApi() {
return this.api
}
@Override
Head getHead() {
return this.head
}
@Override
void start() {}
@Override
void stop() {}
@Override
boolean isRunning() {
return true
}
}

View File

@@ -19,14 +19,12 @@ package io.emeraldpay.dshackle.test
import io.emeraldpay.dshackle.config.UpstreamsConfig
import io.emeraldpay.dshackle.data.BlockContainer
import io.emeraldpay.dshackle.upstream.Head
import io.emeraldpay.dshackle.upstream.calls.AggregatedCallMethods
import io.emeraldpay.dshackle.upstream.calls.CallMethods
import io.emeraldpay.dshackle.startup.QuorumForLabels
import io.emeraldpay.dshackle.upstream.calls.DefaultBitcoinMethods
import io.emeraldpay.dshackle.upstream.calls.DefaultEthereumMethods
import io.emeraldpay.dshackle.upstream.calls.DirectCallMethods
import io.emeraldpay.dshackle.upstream.ethereum.EthereumRpcUpstream
import io.emeraldpay.dshackle.upstream.ethereum.EthereumUpstream
import io.emeraldpay.dshackle.upstream.UpstreamAvailability
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
@@ -36,9 +34,10 @@ import io.emeraldpay.grpc.Chain
import org.jetbrains.annotations.NotNull
import org.reactivestreams.Publisher
class EthereumUpstreamMock extends EthereumRpcUpstream {
EthereumHeadMock ethereumHeadMock = new EthereumHeadMock()
class EthereumUpstreamMock extends EthereumUpstream {
EthereumHeadMock ethereumHeadMock
static CallMethods allMethods() {
new AggregatedCallMethods([
@@ -61,32 +60,24 @@ class EthereumUpstreamMock extends EthereumRpcUpstream {
}
EthereumUpstreamMock(@NotNull String id, @NotNull Chain chain, @NotNull Reader<JsonRpcRequest, JsonRpcResponse> api, CallMethods methods) {
super(id, chain, api, null,
super(id, chain,
UpstreamsConfig.Options.getDefaults(),
UpstreamsConfig.UpstreamRole.PRIMARY,
methods,
new QuorumForLabels.QuorumItem(1, new UpstreamsConfig.Labels()),
methods)
new ConnectorFactoryMock(api, new EthereumHeadMock()))
this.ethereumHeadMock = this.getHead() as EthereumHeadMock
setLag(0)
setStatus(UpstreamAvailability.OK)
start()
}
void nextBlock(BlockContainer block) {
ethereumHeadMock.nextBlock(block)
this.ethereumHeadMock.nextBlock(block)
}
void setBlocks(Publisher<BlockContainer> blocks) {
ethereumHeadMock.predefined = blocks
}
@Override
Head createHead() {
return ethereumHeadMock
}
@Override
Head getHead() {
return ethereumHeadMock
this.ethereumHeadMock.predefined = blocks
}
@Override

View File

@@ -21,11 +21,9 @@ import io.emeraldpay.dshackle.startup.QuorumForLabels
import io.emeraldpay.dshackle.test.EthereumApiStub
import io.emeraldpay.dshackle.test.TestingCommons
import io.emeraldpay.dshackle.upstream.calls.DefaultEthereumMethods
import io.emeraldpay.dshackle.upstream.ethereum.EthereumRpcUpstream
import io.emeraldpay.dshackle.upstream.ethereum.EthereumUpstream
import io.emeraldpay.dshackle.upstream.ethereum.EthereumWsFactory
import io.emeraldpay.dshackle.upstream.ethereum.connectors.EthereumConnectorFactory
import io.emeraldpay.grpc.Chain
import reactor.core.publisher.Flux
import reactor.test.StepVerifier
import spock.lang.Retry
import spock.lang.Specification
@@ -46,15 +44,18 @@ class FilteredApisSpec extends Specification {
[test: "foo"],
[test: "baz"]
].collect {
new EthereumRpcUpstream(
def httpFactory = Mock(HttpFactory) {
create(_, _) >> TestingCommons.api().tap { it.id = "${i++}" }
}
def connectorFactory = new EthereumConnectorFactory(false, null, httpFactory)
new EthereumUpstream(
"test",
Chain.ETHEREUM,
TestingCommons.api().tap { it.id = "${i++}" },
(EthereumWsFactory) null,
new UpstreamsConfig.Options(),
UpstreamsConfig.UpstreamRole.PRIMARY,
ethereumTargets,
new QuorumForLabels.QuorumItem(1, UpstreamsConfig.Labels.fromMap(it)),
ethereumTargets
connectorFactory
)
}
def matcher = new Selector.LabelMatcher("test", ["foo"])

View File

@@ -0,0 +1,9 @@
upstreams:
- id: eth2-1
chain: ropsten
connection:
ethereum-pos:
execution:
rpc:
url: "http://34.106.60.110:8545"
block-priority: 100