@@ -1,59 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2019 ETCDEV GmbH
|
||||
* Copyright (c) 2020 EmeraldPay, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.emeraldpay.dshackle.config
|
||||
|
||||
import io.emeraldpay.dshackle.Chain
|
||||
import io.emeraldpay.dshackle.FileResolver
|
||||
import spock.lang.Specification
|
||||
|
||||
import java.time.Duration
|
||||
|
||||
class ChainsConfigReaderSpec extends Specification {
|
||||
|
||||
ChainsConfigReader reader = new ChainsConfigReader(
|
||||
new UpstreamsConfigReader(Stub(FileResolver))
|
||||
)
|
||||
|
||||
def "Parse standard config"() {
|
||||
setup:
|
||||
def stream = this.class.getClassLoader().getResourceAsStream("configs/chains-basic.yaml")
|
||||
when:
|
||||
def config = reader.read(stream)
|
||||
def eth = config.resolve(Chain.ETHEREUM__MAINNET)
|
||||
def pol = config.resolve(Chain.POLYGON_POS__MAINNET)
|
||||
def opt = config.resolve(Chain.OPTIMISM__MAINNET)
|
||||
def sep = config.resolve(Chain.ETHEREUM__SEPOLIA)
|
||||
then:
|
||||
eth.laggingLagSize == 1
|
||||
eth.syncingLagSize == 6
|
||||
eth.callLimitContract == "0x32268860cAAc2948Ab5DdC7b20db5a420467Cf96"
|
||||
eth.expectedBlockTime == Duration.ofSeconds(12)
|
||||
|
||||
pol.laggingLagSize == 10
|
||||
pol.syncingLagSize == 20
|
||||
pol.expectedBlockTime == Duration.ofMillis(2700)
|
||||
|
||||
opt.laggingLagSize == 3
|
||||
opt.syncingLagSize == 40
|
||||
opt.options.validatePeers == false
|
||||
opt.expectedBlockTime == Duration.ofMillis(400)
|
||||
|
||||
sep.laggingLagSize == 1
|
||||
sep.syncingLagSize == 10
|
||||
sep.expectedBlockTime == Duration.ofSeconds(12)
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2020 EmeraldPay, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.emeraldpay.dshackle.config
|
||||
|
||||
import spock.lang.Specification
|
||||
|
||||
class EnvVariablesSpec extends Specification {
|
||||
|
||||
EnvVariables reader = new EnvVariables()
|
||||
|
||||
def "Post process for usual strings"() {
|
||||
expect:
|
||||
s == reader.postProcess(s)
|
||||
where:
|
||||
s << ["", "a", "13143", "/etc/client1.myservice.com.key", "true", "1a68f20154fc258fe4149c199ad8f281"]
|
||||
}
|
||||
|
||||
def "Post process replaces from env"() {
|
||||
setup:
|
||||
System.setProperty("id", "1")
|
||||
System.setProperty("HOME", "/home/user")
|
||||
System.setProperty("PASSWORD", "1a68f20154fc258fe4149c199ad8f281")
|
||||
expect:
|
||||
replaced == reader.postProcess(orig)
|
||||
where:
|
||||
orig | replaced
|
||||
"p_\${id}" | "p_1"
|
||||
"home: \${HOME}" | "home: /home/user"
|
||||
"\${PASSWORD}" | "1a68f20154fc258fe4149c199ad8f281"
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ class MainConfigReaderSpec extends Specification {
|
||||
port == 8082
|
||||
tls != null
|
||||
routes != null
|
||||
routes.size() == 5
|
||||
routes.size() == 3
|
||||
with(routes[0]) {
|
||||
id == "eth"
|
||||
blockchain == Chain.ETHEREUM__MAINNET
|
||||
@@ -61,17 +61,9 @@ class MainConfigReaderSpec extends Specification {
|
||||
blockchain == Chain.ETHEREUM_CLASSIC__MAINNET
|
||||
}
|
||||
with(routes[2]) {
|
||||
id == "kovan"
|
||||
blockchain == Chain.ETHEREUM__KOVAN
|
||||
}
|
||||
with(routes[3]) {
|
||||
id == "goerli"
|
||||
blockchain == Chain.ETHEREUM__GOERLI
|
||||
}
|
||||
with(routes[4]) {
|
||||
id == "rinkeby"
|
||||
blockchain == Chain.ETHEREUM__RINKEBY
|
||||
}
|
||||
}
|
||||
with(act.health) {
|
||||
it.enabled
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
*/
|
||||
package io.emeraldpay.dshackle.config
|
||||
|
||||
|
||||
import io.emeraldpay.dshackle.foundation.ChainOptions
|
||||
import io.emeraldpay.dshackle.foundation.ChainOptionsReader
|
||||
import io.emeraldpay.dshackle.test.TestingCommons
|
||||
import spock.lang.Specification
|
||||
|
||||
@@ -24,7 +25,7 @@ import java.time.Duration
|
||||
|
||||
class UpstreamsConfigReaderSpec extends Specification {
|
||||
|
||||
UpstreamsConfigReader reader = new UpstreamsConfigReader(TestingCommons.fileResolver())
|
||||
UpstreamsConfigReader reader = new UpstreamsConfigReader(TestingCommons.fileResolver(), new ChainOptionsReader())
|
||||
|
||||
def "Parse standard config"() {
|
||||
setup:
|
||||
@@ -489,8 +490,8 @@ class UpstreamsConfigReaderSpec extends Specification {
|
||||
|
||||
def "Merge options for disableValidation"() {
|
||||
expect:
|
||||
def a = new UpstreamsConfig.PartialOptions().tap { disableValidation = base }
|
||||
def b = new UpstreamsConfig.PartialOptions().tap { disableValidation = overwrite }
|
||||
def a = new ChainOptions.PartialOptions().tap { disableValidation = base }
|
||||
def b = new ChainOptions.PartialOptions().tap { disableValidation = overwrite }
|
||||
def result = a.merge(b).buildOptions()
|
||||
result.disableValidation == exp
|
||||
|
||||
@@ -511,8 +512,8 @@ class UpstreamsConfigReaderSpec extends Specification {
|
||||
|
||||
def "Merge options for providesBalance"() {
|
||||
expect:
|
||||
def a = new UpstreamsConfig.PartialOptions().tap { providesBalance = base }
|
||||
def b = new UpstreamsConfig.PartialOptions().tap { providesBalance = overwrite }
|
||||
def a = new ChainOptions.PartialOptions().tap { providesBalance = base }
|
||||
def b = new ChainOptions.PartialOptions().tap { providesBalance = overwrite }
|
||||
def result = a.merge(b).buildOptions()
|
||||
result.providesBalance == exp
|
||||
|
||||
@@ -533,8 +534,8 @@ class UpstreamsConfigReaderSpec extends Specification {
|
||||
|
||||
def "Merge options for validatePeers"() {
|
||||
expect:
|
||||
def a = new UpstreamsConfig.PartialOptions().tap { validatePeers = base }
|
||||
def b = new UpstreamsConfig.PartialOptions().tap { validatePeers = overwrite }
|
||||
def a = new ChainOptions.PartialOptions().tap { validatePeers = base }
|
||||
def b = new ChainOptions.PartialOptions().tap { validatePeers = overwrite }
|
||||
def result = a.merge(b).buildOptions()
|
||||
result.validatePeers == exp
|
||||
|
||||
@@ -555,8 +556,8 @@ class UpstreamsConfigReaderSpec extends Specification {
|
||||
|
||||
def "Merge options for validateSyncing"() {
|
||||
expect:
|
||||
def a = new UpstreamsConfig.PartialOptions().tap { validateSyncing = base }
|
||||
def b = new UpstreamsConfig.PartialOptions().tap { validateSyncing = overwrite }
|
||||
def a = new ChainOptions.PartialOptions().tap { validateSyncing = base }
|
||||
def b = new ChainOptions.PartialOptions().tap { validateSyncing = overwrite }
|
||||
def result = a.merge(b).buildOptions()
|
||||
result.validateSyncing == exp
|
||||
|
||||
@@ -577,10 +578,10 @@ class UpstreamsConfigReaderSpec extends Specification {
|
||||
|
||||
def "Merge options for timeout"() {
|
||||
expect:
|
||||
def a = new UpstreamsConfig.PartialOptions().tap {
|
||||
def a = new ChainOptions.PartialOptions().tap {
|
||||
timeout = base == null ? null : Duration.ofSeconds(base)
|
||||
}
|
||||
def b = new UpstreamsConfig.PartialOptions().tap {
|
||||
def b = new ChainOptions.PartialOptions().tap {
|
||||
timeout = overwrite == null ? null : Duration.ofSeconds(overwrite)
|
||||
}
|
||||
def result = a.merge(b).buildOptions()
|
||||
@@ -598,8 +599,8 @@ class UpstreamsConfigReaderSpec extends Specification {
|
||||
|
||||
def "Merge options for minPeers"() {
|
||||
expect:
|
||||
def a = new UpstreamsConfig.PartialOptions().tap { minPeers = base }
|
||||
def b = new UpstreamsConfig.PartialOptions().tap { minPeers = overwrite }
|
||||
def a = new ChainOptions.PartialOptions().tap { minPeers = base }
|
||||
def b = new ChainOptions.PartialOptions().tap { minPeers = overwrite }
|
||||
def result = a.merge(b).buildOptions()
|
||||
result.minPeers == exp
|
||||
|
||||
@@ -614,8 +615,8 @@ class UpstreamsConfigReaderSpec extends Specification {
|
||||
|
||||
def "Merge options for validationInterval"() {
|
||||
expect:
|
||||
def a = new UpstreamsConfig.PartialOptions().tap { validationInterval = base }
|
||||
def b = new UpstreamsConfig.PartialOptions().tap { validationInterval = overwrite }
|
||||
def a = new ChainOptions.PartialOptions().tap { validationInterval = base }
|
||||
def b = new ChainOptions.PartialOptions().tap { validationInterval = overwrite }
|
||||
def result = a.merge(b).buildOptions()
|
||||
result.validationInterval == exp
|
||||
|
||||
@@ -630,11 +631,11 @@ class UpstreamsConfigReaderSpec extends Specification {
|
||||
|
||||
def "Options with default values"() {
|
||||
setup:
|
||||
def partialOptions = new UpstreamsConfig.PartialOptions()
|
||||
def partialOptions = new ChainOptions.PartialOptions()
|
||||
when:
|
||||
def options = partialOptions.buildOptions()
|
||||
then:
|
||||
options == new UpstreamsConfig.Options(
|
||||
options == new ChainOptions.Options(
|
||||
false, false, 30, Duration.ofSeconds(60), null, true, 1, true, true, true
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 EmeraldPay, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.emeraldpay.dshackle.config
|
||||
|
||||
import org.jetbrains.annotations.Nullable
|
||||
import org.yaml.snakeyaml.Yaml
|
||||
import org.yaml.snakeyaml.nodes.MappingNode
|
||||
import spock.lang.Specification
|
||||
|
||||
class YamlConfigReaderSpec extends Specification {
|
||||
|
||||
def "reads bytes values"() {
|
||||
setup:
|
||||
def rdr = new Impl()
|
||||
expect:
|
||||
rdr.getValueAsBytes(asNode("test", input), "test") == exp
|
||||
where:
|
||||
input | exp
|
||||
"1024" | 1024
|
||||
"1k" | 1024
|
||||
"1kb" | 1024
|
||||
"1K" | 1024
|
||||
"16kb" | 16 * 1024
|
||||
"1M" | 1024 * 1024
|
||||
"4mb" | 4 * 1024 * 1024
|
||||
}
|
||||
|
||||
private MappingNode asNode(String key, String value) {
|
||||
return new Yaml().compose(new StringReader("$key: $value")) as MappingNode
|
||||
}
|
||||
|
||||
class Impl extends YamlConfigReader {
|
||||
@Override
|
||||
Object read(@Nullable MappingNode input) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -292,7 +292,7 @@ class NativeCallSpec extends Specification {
|
||||
def nativeCall = nativeCall(upstreams)
|
||||
|
||||
def req = BlockchainOuterClass.NativeCallRequest.newBuilder()
|
||||
.setChainValue(Chain.ETHEREUM__MORDEN.id)
|
||||
.setChainValue(Chain.ETHEREUM__GOERLI.id)
|
||||
.addAllItems([1, 2].collect { id ->
|
||||
return BlockchainOuterClass.NativeCallItem.newBuilder()
|
||||
.setId(id)
|
||||
@@ -300,7 +300,7 @@ class NativeCallSpec extends Specification {
|
||||
.build()
|
||||
})
|
||||
.build()
|
||||
1 * upstreams.isAvailable(Chain.ETHEREUM__MORDEN) >> false
|
||||
1 * upstreams.isAvailable(Chain.ETHEREUM__GOERLI) >> false
|
||||
when:
|
||||
def resp = nativeCall.prepareCall(req)
|
||||
then:
|
||||
|
||||
@@ -17,10 +17,9 @@
|
||||
package io.emeraldpay.dshackle.test
|
||||
|
||||
import io.emeraldpay.dshackle.Chain
|
||||
import io.emeraldpay.dshackle.config.ChainsConfig
|
||||
import io.emeraldpay.dshackle.config.ChainsConfig.ChainConfig
|
||||
import io.emeraldpay.dshackle.config.UpstreamsConfig
|
||||
import io.emeraldpay.dshackle.config.UpstreamsConfig.Options
|
||||
import io.emeraldpay.dshackle.foundation.ChainOptions
|
||||
import io.emeraldpay.dshackle.data.BlockContainer
|
||||
import io.emeraldpay.dshackle.reader.Reader
|
||||
import io.emeraldpay.dshackle.startup.QuorumForLabels
|
||||
@@ -31,6 +30,7 @@ import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import org.jetbrains.annotations.NotNull
|
||||
import org.reactivestreams.Publisher
|
||||
import io.emeraldpay.dshackle.foundation.ChainOptions
|
||||
|
||||
class EthereumPosRpcUpstreamMock extends EthereumLikeRpcUpstream {
|
||||
EthereumHeadMock ethereumHeadMock
|
||||
@@ -80,8 +80,8 @@ class EthereumPosRpcUpstreamMock extends EthereumLikeRpcUpstream {
|
||||
start()
|
||||
}
|
||||
|
||||
static Options getOpts() {
|
||||
def opt = UpstreamsConfig.PartialOptions.getDefaults()
|
||||
static ChainOptions.Options getOpts() {
|
||||
def opt = ChainOptions.PartialOptions.getDefaults()
|
||||
opt.setDisableValidation(true)
|
||||
opt.setDisableUpstreamValidation(true)
|
||||
return opt.buildOptions()
|
||||
|
||||
@@ -28,6 +28,7 @@ import io.emeraldpay.dshackle.upstream.ethereum.EthereumLikeRpcUpstream
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import org.jetbrains.annotations.NotNull
|
||||
import io.emeraldpay.dshackle.foundation.ChainOptions
|
||||
import org.reactivestreams.Publisher
|
||||
|
||||
class EthereumRpcUpstreamMock extends EthereumLikeRpcUpstream {
|
||||
@@ -56,7 +57,7 @@ class EthereumRpcUpstreamMock extends EthereumLikeRpcUpstream {
|
||||
|
||||
EthereumRpcUpstreamMock(@NotNull String id, @NotNull Chain chain, @NotNull Reader<JsonRpcRequest, JsonRpcResponse> api, CallMethods methods) {
|
||||
super(id, id.hashCode().byteValue(), chain,
|
||||
UpstreamsConfig.PartialOptions.getDefaults().buildOptions(),
|
||||
ChainOptions.PartialOptions.getDefaults().buildOptions(),
|
||||
UpstreamsConfig.UpstreamRole.PRIMARY,
|
||||
methods,
|
||||
new QuorumForLabels.QuorumItem(1, new UpstreamsConfig.Labels()),
|
||||
|
||||
@@ -29,6 +29,7 @@ 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
|
||||
|
||||
import java.time.Duration
|
||||
@@ -66,7 +67,7 @@ class FilteredApisSpec extends Specification {
|
||||
"test",
|
||||
(byte) 123,
|
||||
Chain.ETHEREUM__MAINNET,
|
||||
new UpstreamsConfig.PartialOptions().buildOptions(),
|
||||
new ChainOptions.PartialOptions().buildOptions(),
|
||||
UpstreamsConfig.UpstreamRole.PRIMARY,
|
||||
ethereumTargets,
|
||||
new QuorumForLabels.QuorumItem(1, UpstreamsConfig.Labels.fromMap(it)),
|
||||
|
||||
@@ -39,9 +39,7 @@ class DefaultEthereumMethodsSpec extends Specification {
|
||||
chain | id
|
||||
Chain.ETHEREUM__MAINNET | '"0x1"'
|
||||
Chain.ETHEREUM_CLASSIC__MAINNET | '"0x3d"'
|
||||
Chain.ETHEREUM__KOVAN | '"0x2a"'
|
||||
Chain.ETHEREUM__GOERLI | '"0x5"'
|
||||
Chain.ETHEREUM__RINKEBY | '"0x4"'
|
||||
Chain.ETHEREUM__ROPSTEN | '"0x3"'
|
||||
}
|
||||
|
||||
@@ -61,7 +59,7 @@ class DefaultEthereumMethodsSpec extends Specification {
|
||||
new DefaultEthereumMethods(chain).getSupportedMethods().containsAll(methods)
|
||||
where:
|
||||
chain | methods
|
||||
Chain.POLYGON_POS__MAINNET | ["bor_getAuthor",
|
||||
Chain.POLYGON__MAINNET | ["bor_getAuthor",
|
||||
"bor_getCurrentValidators",
|
||||
"bor_getCurrentProposer",
|
||||
"bor_getRootHash",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
package io.emeraldpay.dshackle.upstream.ethereum
|
||||
|
||||
|
||||
import io.emeraldpay.dshackle.config.UpstreamsConfig
|
||||
import io.emeraldpay.dshackle.foundation.ChainOptions
|
||||
import io.emeraldpay.dshackle.reader.Reader
|
||||
import io.emeraldpay.dshackle.test.ApiReaderMock
|
||||
import io.emeraldpay.dshackle.test.TestingCommons
|
||||
@@ -43,7 +43,7 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
|
||||
def "Resolve to final availability"() {
|
||||
setup:
|
||||
def validator = new EthereumUpstreamValidator(ETHEREUM__MAINNET, Stub(EthereumLikeUpstream), UpstreamsConfig.PartialOptions.getDefaults().buildOptions())
|
||||
def validator = new EthereumUpstreamValidator(ETHEREUM__MAINNET, Stub(EthereumLikeUpstream), ChainOptions.PartialOptions.getDefaults().buildOptions())
|
||||
expect:
|
||||
validator.resolve(Tuples.of(sync, peers, call)) == exp
|
||||
where:
|
||||
@@ -61,7 +61,7 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
|
||||
def "Doesnt check eth_syncing when disabled"() {
|
||||
setup:
|
||||
def options = UpstreamsConfig.PartialOptions.getDefaults().tap {
|
||||
def options = ChainOptions.PartialOptions.getDefaults().tap {
|
||||
it.validateSyncing = false
|
||||
}.buildOptions()
|
||||
def up = Mock(EthereumLikeUpstream)
|
||||
@@ -76,7 +76,7 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
|
||||
def "Syncing is OK when false returned from upstream"() {
|
||||
setup:
|
||||
def options = UpstreamsConfig.PartialOptions.getDefaults().tap {
|
||||
def options = ChainOptions.PartialOptions.getDefaults().tap {
|
||||
it.validateSyncing = true
|
||||
}.buildOptions()
|
||||
def up = TestingCommons.upstream(
|
||||
@@ -94,7 +94,7 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
|
||||
def "Execute onSyncingNode with result of eth_syncing"() {
|
||||
setup:
|
||||
def options = UpstreamsConfig.PartialOptions.getDefaults().tap {
|
||||
def options = ChainOptions.PartialOptions.getDefaults().tap {
|
||||
it.validateSyncing = true
|
||||
}.buildOptions()
|
||||
def up = Mock(EthereumLikeUpstream) {
|
||||
@@ -121,7 +121,7 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
|
||||
def "Syncing is SYNCING when state returned from upstream"() {
|
||||
setup:
|
||||
def options = UpstreamsConfig.PartialOptions.getDefaults().tap {
|
||||
def options = ChainOptions.PartialOptions.getDefaults().tap {
|
||||
it.validateSyncing = true
|
||||
}.buildOptions()
|
||||
def up = TestingCommons.upstream(
|
||||
@@ -139,7 +139,7 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
|
||||
def "Syncing is UNAVAILABLE when error returned from upstream"() {
|
||||
setup:
|
||||
def options = UpstreamsConfig.PartialOptions.getDefaults().tap {
|
||||
def options = ChainOptions.PartialOptions.getDefaults().tap {
|
||||
it.validateSyncing = true
|
||||
}.buildOptions()
|
||||
def up = TestingCommons.upstream(
|
||||
@@ -157,7 +157,7 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
|
||||
def "Doesnt validate peers when disabled"() {
|
||||
setup:
|
||||
def options = UpstreamsConfig.PartialOptions.getDefaults().tap {
|
||||
def options = ChainOptions.PartialOptions.getDefaults().tap {
|
||||
it.validatePeers = false
|
||||
it.minPeers = 10
|
||||
}.buildOptions()
|
||||
@@ -173,7 +173,7 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
|
||||
def "Doesnt validate peers when zero peers is expected"() {
|
||||
setup:
|
||||
def options = UpstreamsConfig.PartialOptions.getDefaults().tap {
|
||||
def options = ChainOptions.PartialOptions.getDefaults().tap {
|
||||
it.validatePeers = true
|
||||
it.minPeers = 0
|
||||
}.buildOptions()
|
||||
@@ -189,7 +189,7 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
|
||||
def "Peers is IMMATURE when state returned too few peers"() {
|
||||
setup:
|
||||
def options = UpstreamsConfig.PartialOptions.getDefaults().tap {
|
||||
def options = ChainOptions.PartialOptions.getDefaults().tap {
|
||||
it.validatePeers = true
|
||||
it.minPeers = 10
|
||||
}.buildOptions()
|
||||
@@ -208,7 +208,7 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
|
||||
def "Peers is OK when state returned exactly min peers"() {
|
||||
setup:
|
||||
def options = UpstreamsConfig.PartialOptions.getDefaults().tap {
|
||||
def options = ChainOptions.PartialOptions.getDefaults().tap {
|
||||
it.validatePeers = true
|
||||
it.minPeers = 10
|
||||
}.buildOptions()
|
||||
@@ -227,7 +227,7 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
|
||||
def "Peers is OK when state returned more than enough peers"() {
|
||||
setup:
|
||||
def options = UpstreamsConfig.PartialOptions.getDefaults().tap {
|
||||
def options = ChainOptions.PartialOptions.getDefaults().tap {
|
||||
it.validatePeers = true
|
||||
it.minPeers = 10
|
||||
}.buildOptions()
|
||||
@@ -246,7 +246,7 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
|
||||
def "Peers is UNAVAILABLE when state returned error"() {
|
||||
setup:
|
||||
def options = UpstreamsConfig.PartialOptions.getDefaults().tap {
|
||||
def options = ChainOptions.PartialOptions.getDefaults().tap {
|
||||
it.validatePeers = true
|
||||
it.minPeers = 10
|
||||
}.buildOptions()
|
||||
@@ -265,7 +265,7 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
|
||||
def "Doesnt validate chan and callLimit when disabled"() {
|
||||
setup:
|
||||
def options = UpstreamsConfig.PartialOptions.getDefaults().tap {
|
||||
def options = ChainOptions.PartialOptions.getDefaults().tap {
|
||||
it.validateCalllimit = false
|
||||
it.validateChain = false
|
||||
}.buildOptions()
|
||||
@@ -287,7 +287,7 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
|
||||
def "Upstream is valid if not error from call limit check"() {
|
||||
setup:
|
||||
def options = UpstreamsConfig.PartialOptions.getDefaults().tap {
|
||||
def options = ChainOptions.PartialOptions.getDefaults().tap {
|
||||
it.validateChain = false
|
||||
}.buildOptions()
|
||||
def up = Mock(EthereumLikeRpcUpstream) {
|
||||
@@ -311,7 +311,7 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
|
||||
def "Upstream is not valid if error returned on call limit check"() {
|
||||
setup:
|
||||
def options = UpstreamsConfig.PartialOptions.getDefaults().tap {
|
||||
def options = ChainOptions.PartialOptions.getDefaults().tap {
|
||||
it.validateChain = false
|
||||
}.buildOptions()
|
||||
def up = Mock(EthereumLikeRpcUpstream) {
|
||||
@@ -335,7 +335,7 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
|
||||
def "Upstream is valid if chain settings are valid"() {
|
||||
setup:
|
||||
def options = UpstreamsConfig.PartialOptions.getDefaults().tap {
|
||||
def options = ChainOptions.PartialOptions.getDefaults().tap {
|
||||
it.validateCalllimit = false
|
||||
}.buildOptions()
|
||||
def up = Mock(EthereumLikeRpcUpstream) {
|
||||
@@ -357,7 +357,7 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
|
||||
def "Upstream is not valid - specified optimism but got ethereum"() {
|
||||
setup:
|
||||
def options = UpstreamsConfig.PartialOptions.getDefaults().tap {
|
||||
def options = ChainOptions.PartialOptions.getDefaults().tap {
|
||||
it.validateCalllimit = false
|
||||
}.buildOptions()
|
||||
def up = Mock(EthereumLikeRpcUpstream) {
|
||||
@@ -379,7 +379,7 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
|
||||
def "Upstream is valid if all setting are valid"() {
|
||||
setup:
|
||||
def options = UpstreamsConfig.PartialOptions.getDefaults().buildOptions()
|
||||
def options = ChainOptions.PartialOptions.getDefaults().buildOptions()
|
||||
def up = Mock(EthereumLikeRpcUpstream) {
|
||||
5 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_chainId", emptyList())) >> Mono.just(new JsonRpcResponse('"0x1"'.getBytes(), null))
|
||||
@@ -403,7 +403,7 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
|
||||
def "Upstream is not valid if there are errors"() {
|
||||
setup:
|
||||
def options = UpstreamsConfig.PartialOptions.getDefaults().buildOptions()
|
||||
def options = ChainOptions.PartialOptions.getDefaults().buildOptions()
|
||||
def up = Mock(EthereumLikeRpcUpstream) {
|
||||
5 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_chainId", emptyList())) >> Mono.just(new JsonRpcResponse(null, new JsonRpcError(1, "Too long")))
|
||||
|
||||
@@ -38,7 +38,6 @@ import io.grpc.stub.StreamObserver
|
||||
import io.micrometer.core.instrument.Counter
|
||||
import io.micrometer.core.instrument.Timer
|
||||
import reactor.core.scheduler.Schedulers
|
||||
import reactor.test.StepVerifier
|
||||
import spock.lang.Specification
|
||||
|
||||
import java.time.Duration
|
||||
|
||||
@@ -6,6 +6,7 @@ import io.emeraldpay.api.proto.Common.ChainRef
|
||||
import io.emeraldpay.dshackle.config.MainConfig
|
||||
import io.emeraldpay.dshackle.config.MainConfigReader
|
||||
import io.emeraldpay.dshackle.config.UpstreamsConfig
|
||||
import io.emeraldpay.dshackle.foundation.ChainOptions
|
||||
import io.github.ganchix.ganache.Account
|
||||
import io.github.ganchix.ganache.GanacheContainer
|
||||
import io.grpc.BindableService
|
||||
@@ -43,8 +44,8 @@ class IntegrationTest {
|
||||
withAccounts(
|
||||
listOf(
|
||||
Account.builder().privateKey(PRIVATE_KEY_0).balance(BigInteger.valueOf(2000000000000000000)).build(),
|
||||
Account.builder().privateKey(PRIVATE_KEY_1).balance(BigInteger.valueOf(2000000000000000000)).build()
|
||||
)
|
||||
Account.builder().privateKey(PRIVATE_KEY_1).balance(BigInteger.valueOf(2000000000000000000)).build(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -82,7 +83,7 @@ class IntegrationTest {
|
||||
val reader = MainConfigReader(fileResolver)
|
||||
val config = reader.read(
|
||||
ResourceUtils.getFile("classpath:integration/dshackle.yaml")
|
||||
.inputStream()
|
||||
.inputStream(),
|
||||
)!!
|
||||
patch(config)
|
||||
return config
|
||||
@@ -94,7 +95,7 @@ class IntegrationTest {
|
||||
id = "ganache"
|
||||
nodeId = 1
|
||||
chain = "ethereum"
|
||||
options = UpstreamsConfig.PartialOptions()
|
||||
options = ChainOptions.PartialOptions()
|
||||
.apply {
|
||||
validateChain = false
|
||||
}
|
||||
@@ -102,12 +103,12 @@ class IntegrationTest {
|
||||
execution = UpstreamsConfig.EthereumConnection().apply {
|
||||
rpc = UpstreamsConfig.HttpEndpoint(
|
||||
URI.create(
|
||||
"http://" + ganacheContainer.getHost() + ":" + ganacheContainer.getMappedPort(8545) + "/"
|
||||
)
|
||||
"http://" + ganacheContainer.getHost() + ":" + ganacheContainer.getMappedPort(8545) + "/",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
package io.emeraldpay.dshackle.config
|
||||
|
||||
import io.emeraldpay.dshackle.Chain
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
internal class ChainsConfigTest {
|
||||
|
||||
@Test
|
||||
fun patch() {
|
||||
val orig = ChainsConfig(
|
||||
mapOf(
|
||||
Chain.BITCOIN__MAINNET to createRawChainConfig(0, 0),
|
||||
Chain.ETHEREUM__MAINNET to createRawChainConfig(1, 2),
|
||||
Chain.POLYGON_POS__MAINNET to createRawChainConfig(3, 4)
|
||||
),
|
||||
createRawChainConfig(1, 2)
|
||||
)
|
||||
|
||||
val patch = ChainsConfig(
|
||||
mapOf(
|
||||
Chain.BITCOIN__MAINNET to createRawChainConfig(null, 10000),
|
||||
Chain.POLYGON_POS__MAINNET to createRawChainConfig(10, 11),
|
||||
Chain.ARBITRUM__MAINNET to createRawChainConfig(999, 999)
|
||||
),
|
||||
createRawChainConfig(100, null)
|
||||
)
|
||||
|
||||
val res = orig.patch(patch)
|
||||
|
||||
assertEquals(
|
||||
ChainsConfig(
|
||||
mapOf(
|
||||
Chain.BITCOIN__MAINNET to createRawChainConfig(0, 10000),
|
||||
Chain.ETHEREUM__MAINNET to createRawChainConfig(1, 2),
|
||||
Chain.POLYGON_POS__MAINNET to createRawChainConfig(10, 11),
|
||||
Chain.ARBITRUM__MAINNET to createRawChainConfig(999, 999)
|
||||
),
|
||||
createRawChainConfig(100, 2)
|
||||
),
|
||||
res
|
||||
)
|
||||
}
|
||||
|
||||
private fun createRawChainConfig(syncingLagSize: Int?, laggingLagSize: Int?) =
|
||||
ChainsConfig.RawChainConfig()
|
||||
.apply {
|
||||
this.syncingLagSize = syncingLagSize
|
||||
this.laggingLagSize = laggingLagSize
|
||||
}
|
||||
}
|
||||
@@ -15,21 +15,21 @@ internal class UpstreamsConfigTest {
|
||||
return Stream.of(
|
||||
Arguments.of(
|
||||
UpstreamsConfig.EthereumConnection(),
|
||||
ConnectorMode.RPC_ONLY
|
||||
ConnectorMode.RPC_ONLY,
|
||||
),
|
||||
Arguments.of(
|
||||
UpstreamsConfig.EthereumConnection()
|
||||
.apply {
|
||||
ws = UpstreamsConfig.WsEndpoint(URI("ws://localhost:8546"))
|
||||
},
|
||||
ConnectorMode.WS_ONLY
|
||||
ConnectorMode.WS_ONLY,
|
||||
),
|
||||
Arguments.of(
|
||||
UpstreamsConfig.EthereumConnection()
|
||||
.apply {
|
||||
ws = UpstreamsConfig.WsEndpoint(URI("ws://localhost:8546"))
|
||||
},
|
||||
ConnectorMode.WS_ONLY
|
||||
ConnectorMode.WS_ONLY,
|
||||
),
|
||||
Arguments.of(
|
||||
UpstreamsConfig.EthereumConnection()
|
||||
@@ -37,7 +37,7 @@ internal class UpstreamsConfigTest {
|
||||
connectorMode = "RPC_REQUESTS_WITH_WS_HEAD"
|
||||
ws = UpstreamsConfig.WsEndpoint(URI("ws://localhost:8546"))
|
||||
},
|
||||
ConnectorMode.RPC_REQUESTS_WITH_WS_HEAD
|
||||
ConnectorMode.RPC_REQUESTS_WITH_WS_HEAD,
|
||||
),
|
||||
Arguments.of(
|
||||
UpstreamsConfig.EthereumConnection()
|
||||
@@ -45,7 +45,7 @@ internal class UpstreamsConfigTest {
|
||||
connectorMode = "RPC_REQUESTS_WITH_MIXED_HEAD"
|
||||
ws = UpstreamsConfig.WsEndpoint(URI("ws://localhost:8546"))
|
||||
},
|
||||
ConnectorMode.RPC_REQUESTS_WITH_MIXED_HEAD
|
||||
ConnectorMode.RPC_REQUESTS_WITH_MIXED_HEAD,
|
||||
),
|
||||
Arguments.of(
|
||||
UpstreamsConfig.EthereumConnection()
|
||||
@@ -53,7 +53,7 @@ internal class UpstreamsConfigTest {
|
||||
rpc = UpstreamsConfig.HttpEndpoint(URI("http://localhost:8546"))
|
||||
ws = UpstreamsConfig.WsEndpoint(URI("ws://localhost:8546"))
|
||||
},
|
||||
ConnectorMode.RPC_REQUESTS_WITH_WS_HEAD
|
||||
ConnectorMode.RPC_REQUESTS_WITH_WS_HEAD,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
version: v1
|
||||
|
||||
chain-settings:
|
||||
default:
|
||||
lags:
|
||||
syncing: 6
|
||||
lagging: 1
|
||||
expected-block-time: 12s
|
||||
chains:
|
||||
- id: eth
|
||||
call-validate-contract: 0x32268860cAAc2948Ab5DdC7b20db5a420467Cf96
|
||||
expected-block-time: 12s
|
||||
lags:
|
||||
syncing: 6
|
||||
lagging: 1
|
||||
- id: optimism
|
||||
expected-block-time: 400ms
|
||||
lags:
|
||||
lagging: 3
|
||||
- id: sepolia
|
||||
lags:
|
||||
syncing: 10
|
||||
@@ -45,13 +45,8 @@ proxy:
|
||||
blockchain: ethereum
|
||||
- id: etc
|
||||
blockchain: ethereum_classic
|
||||
- id: kovan
|
||||
blockchain: kovan
|
||||
- id: goerli
|
||||
blockchain: goerli
|
||||
- id: rinkeby
|
||||
blockchain: rinkeby
|
||||
|
||||
cluster:
|
||||
defaults:
|
||||
- chains:
|
||||
|
||||
Reference in New Issue
Block a user