add grpc support for PoS Ethereum

This commit is contained in:
terminal
2022-07-29 17:42:19 +04:00
parent eb95c591f7
commit 1df7221c68
24 changed files with 302 additions and 230 deletions

View File

@@ -17,9 +17,6 @@
package io.emeraldpay.dshackle.config
import io.emeraldpay.dshackle.test.TestingCommons
import io.emeraldpay.dshackle.upstream.ethereum.EthereumUpstream
import io.emeraldpay.grpc.Chain
import io.emeraldpay.etherjar.rpc.RpcClient
import spock.lang.Specification
class UpstreamsConfigReaderSpec extends Specification {

View File

@@ -22,10 +22,10 @@ import io.emeraldpay.api.proto.BlockchainOuterClass
import io.emeraldpay.api.proto.Common
import io.emeraldpay.dshackle.Global
import io.emeraldpay.dshackle.data.BlockContainer
import io.emeraldpay.dshackle.test.EthereumUpstreamMock
import io.emeraldpay.dshackle.test.EthereumRpcUpstreamMock
import io.emeraldpay.dshackle.test.TestingCommons
import io.emeraldpay.dshackle.test.MultistreamHolderMock
import io.emeraldpay.dshackle.upstream.ethereum.EthereumUpstream
import io.emeraldpay.dshackle.upstream.ethereum.EthereumRpcUpstream
import io.emeraldpay.grpc.Chain
import io.emeraldpay.etherjar.domain.BlockHash
import io.emeraldpay.etherjar.rpc.json.BlockJson
@@ -43,7 +43,7 @@ class StreamHeadSpec extends Specification {
def "Errors on unavailable chain"() {
setup:
def upstreams = new MultistreamHolderMock(Chain.ETHEREUM, Stub(EthereumUpstream))
def upstreams = new MultistreamHolderMock(Chain.ETHEREUM, Stub(EthereumRpcUpstream))
def streamHead = new StreamHead(upstreams)
when:
def flux = streamHead.add(
@@ -78,7 +78,7 @@ class StreamHeadSpec extends Specification {
.build()
}
def upstream = new EthereumUpstreamMock(Chain.ETHEREUM, TestingCommons.api())
def upstream = new EthereumRpcUpstreamMock(Chain.ETHEREUM, TestingCommons.api())
def upstreams = new MultistreamHolderMock(Chain.ETHEREUM, upstream)
def streamHead = new StreamHead(upstreams)
when:

View File

@@ -3,18 +3,12 @@ package io.emeraldpay.dshackle.rpc
import io.emeraldpay.api.proto.BlockchainOuterClass
import io.emeraldpay.api.proto.Common
import io.emeraldpay.dshackle.config.TokensConfig
import io.emeraldpay.dshackle.test.EthereumUpstreamMock
import io.emeraldpay.dshackle.test.MultistreamHolderMock
import io.emeraldpay.dshackle.test.ReaderMock
import io.emeraldpay.dshackle.upstream.MultistreamHolder
import io.emeraldpay.dshackle.upstream.ethereum.ERC20Balance
import io.emeraldpay.dshackle.upstream.ethereum.EthereumMultistream
import io.emeraldpay.dshackle.upstream.ethereum.EthereumSubscribe
import io.emeraldpay.dshackle.upstream.ethereum.EthereumUpstream
import io.emeraldpay.dshackle.upstream.ethereum.subscribe.ConnectLogs
import io.emeraldpay.dshackle.upstream.ethereum.subscribe.json.LogMessage
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.etherjar.domain.BlockHash
import io.emeraldpay.etherjar.domain.TransactionId
import io.emeraldpay.etherjar.hex.Hex32
@@ -22,11 +16,9 @@ import io.emeraldpay.grpc.Chain
import io.emeraldpay.etherjar.domain.Address
import io.emeraldpay.etherjar.erc20.ERC20Token
import io.emeraldpay.etherjar.hex.HexData
import io.emeraldpay.etherjar.rpc.json.TransactionCallJson
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
import reactor.test.StepVerifier
import spock.lang.Ignore
import spock.lang.Specification
import java.time.Duration

View File

@@ -25,7 +25,7 @@ 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.EthereumUpstream
import io.emeraldpay.dshackle.upstream.ethereum.EthereumRpcUpstream
import io.emeraldpay.dshackle.upstream.UpstreamAvailability
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
@@ -35,7 +35,7 @@ import org.jetbrains.annotations.NotNull
import org.reactivestreams.Publisher
class EthereumUpstreamMock extends EthereumUpstream {
class EthereumRpcUpstreamMock extends EthereumRpcUpstream {
EthereumHeadMock ethereumHeadMock
@@ -47,19 +47,19 @@ class EthereumUpstreamMock extends EthereumUpstream {
])
}
EthereumUpstreamMock(@NotNull Chain chain, @NotNull Reader<JsonRpcRequest, JsonRpcResponse> api) {
EthereumRpcUpstreamMock(@NotNull Chain chain, @NotNull Reader<JsonRpcRequest, JsonRpcResponse> api) {
this(chain, api, allMethods())
}
EthereumUpstreamMock(@NotNull String id, @NotNull Chain chain, @NotNull Reader<JsonRpcRequest, JsonRpcResponse> api) {
EthereumRpcUpstreamMock(@NotNull String id, @NotNull Chain chain, @NotNull Reader<JsonRpcRequest, JsonRpcResponse> api) {
this(id, chain, api, allMethods())
}
EthereumUpstreamMock(@NotNull Chain chain, @NotNull Reader<JsonRpcRequest, JsonRpcResponse> api, CallMethods methods) {
EthereumRpcUpstreamMock(@NotNull Chain chain, @NotNull Reader<JsonRpcRequest, JsonRpcResponse> api, CallMethods methods) {
this("test", chain, api, methods)
}
EthereumUpstreamMock(@NotNull String id, @NotNull Chain chain, @NotNull Reader<JsonRpcRequest, JsonRpcResponse> api, CallMethods methods) {
EthereumRpcUpstreamMock(@NotNull String id, @NotNull Chain chain, @NotNull Reader<JsonRpcRequest, JsonRpcResponse> api, CallMethods methods) {
super(id, chain,
UpstreamsConfig.Options.getDefaults(),
UpstreamsConfig.UpstreamRole.PRIMARY,

View File

@@ -28,7 +28,7 @@ import io.emeraldpay.dshackle.upstream.Upstream
import io.emeraldpay.dshackle.upstream.MultistreamHolder
import io.emeraldpay.dshackle.upstream.ethereum.EthereumMultistream
import io.emeraldpay.dshackle.upstream.ethereum.EthereumReader
import io.emeraldpay.dshackle.upstream.ethereum.EthereumUpstream
import io.emeraldpay.dshackle.upstream.ethereum.EthereumRpcUpstream
import io.emeraldpay.grpc.BlockchainType
import io.emeraldpay.grpc.Chain
import org.jetbrains.annotations.NotNull
@@ -48,8 +48,8 @@ class MultistreamHolderMock implements MultistreamHolder {
if (BlockchainType.from(chain) == BlockchainType.ETHEREUM) {
if (up instanceof EthereumMultistream) {
upstreams[chain] = up
} else if (up instanceof EthereumUpstream) {
upstreams[chain] = new EthereumMultistreamMock(chain, [up as EthereumUpstream], Caches.default())
} else if (up instanceof EthereumRpcUpstream) {
upstreams[chain] = new EthereumMultistreamMock(chain, [up as EthereumRpcUpstream], Caches.default())
} else {
throw new IllegalArgumentException("Unsupported upstream type ${up.class}")
}
@@ -105,15 +105,15 @@ class MultistreamHolderMock implements MultistreamHolder {
CallMethods customMethods = null
Head customHead = null
EthereumMultistreamMock(@NotNull Chain chain, @NotNull List<EthereumUpstream> upstreams, @NotNull Caches caches) {
EthereumMultistreamMock(@NotNull Chain chain, @NotNull List<EthereumRpcUpstream> upstreams, @NotNull Caches caches) {
super(chain, upstreams, caches)
}
EthereumMultistreamMock(@NotNull Chain chain, @NotNull List<EthereumUpstream> upstreams) {
EthereumMultistreamMock(@NotNull Chain chain, @NotNull List<EthereumRpcUpstream> upstreams) {
this(chain, upstreams, Caches.default())
}
EthereumMultistreamMock(@NotNull Chain chain, @NotNull EthereumUpstream upstream) {
EthereumMultistreamMock(@NotNull Chain chain, @NotNull EthereumRpcUpstream upstream) {
this(chain, [upstream])
}

View File

@@ -28,7 +28,7 @@ import io.emeraldpay.dshackle.reader.Reader
import io.emeraldpay.dshackle.upstream.Multistream
import io.emeraldpay.dshackle.upstream.calls.DirectCallMethods
import io.emeraldpay.dshackle.upstream.ethereum.EthereumMultistream
import io.emeraldpay.dshackle.upstream.ethereum.EthereumUpstream
import io.emeraldpay.dshackle.upstream.ethereum.EthereumRpcUpstream
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.grpc.Chain
@@ -46,35 +46,35 @@ class TestingCommons {
return new ApiReaderMock()
}
static EthereumUpstreamMock upstream() {
return new EthereumUpstreamMock(Chain.ETHEREUM, api())
static EthereumRpcUpstreamMock upstream() {
return new EthereumRpcUpstreamMock(Chain.ETHEREUM, api())
}
static EthereumUpstreamMock upstream(String id) {
return new EthereumUpstreamMock(id, Chain.ETHEREUM, api())
static EthereumRpcUpstreamMock upstream(String id) {
return new EthereumRpcUpstreamMock(id, Chain.ETHEREUM, api())
}
static EthereumUpstreamMock upstream(String id, Reader<JsonRpcRequest, JsonRpcResponse> api) {
return new EthereumUpstreamMock(id, Chain.ETHEREUM, api)
static EthereumRpcUpstreamMock upstream(String id, Reader<JsonRpcRequest, JsonRpcResponse> api) {
return new EthereumRpcUpstreamMock(id, Chain.ETHEREUM, api)
}
static EthereumUpstreamMock upstream(Reader<JsonRpcRequest, JsonRpcResponse> api) {
return new EthereumUpstreamMock(Chain.ETHEREUM, api)
static EthereumRpcUpstreamMock upstream(Reader<JsonRpcRequest, JsonRpcResponse> api) {
return new EthereumRpcUpstreamMock(Chain.ETHEREUM, api)
}
static EthereumUpstreamMock upstream(Reader<JsonRpcRequest, JsonRpcResponse> api, String method) {
static EthereumRpcUpstreamMock upstream(Reader<JsonRpcRequest, JsonRpcResponse> api, String method) {
return upstream(api, [method])
}
static EthereumUpstreamMock upstream(Reader<JsonRpcRequest, JsonRpcResponse> api, List<String> methods) {
return new EthereumUpstreamMock(Chain.ETHEREUM, api, new DirectCallMethods(methods))
static EthereumRpcUpstreamMock upstream(Reader<JsonRpcRequest, JsonRpcResponse> api, List<String> methods) {
return new EthereumRpcUpstreamMock(Chain.ETHEREUM, api, new DirectCallMethods(methods))
}
static Multistream multistream(Reader<JsonRpcRequest, JsonRpcResponse> api) {
return multistream(upstream(api))
}
static Multistream multistream(EthereumUpstream up) {
static Multistream multistream(EthereumRpcUpstream up) {
return new EthereumMultistream(Chain.ETHEREUM, [up], Caches.default()).tap {
start()
}

View File

@@ -16,7 +16,7 @@
package io.emeraldpay.dshackle.upstream
import io.emeraldpay.dshackle.startup.UpstreamChange
import io.emeraldpay.dshackle.test.EthereumUpstreamMock
import io.emeraldpay.dshackle.test.EthereumRpcUpstreamMock
import io.emeraldpay.dshackle.test.TestingCommons
import io.emeraldpay.grpc.Chain
import spock.lang.Specification
@@ -26,7 +26,7 @@ class CurrentMultistreamHolderSpec extends Specification {
def "add upstream"() {
setup:
def current = new CurrentMultistreamHolder(TestingCommons.emptyCaches())
def up = new EthereumUpstreamMock("test", Chain.ETHEREUM, TestingCommons.api())
def up = new EthereumRpcUpstreamMock("test", Chain.ETHEREUM, TestingCommons.api())
when:
current.update(new UpstreamChange(Chain.ETHEREUM, up, UpstreamChange.ChangeType.ADDED))
then:
@@ -37,9 +37,9 @@ class CurrentMultistreamHolderSpec extends Specification {
def "add multiple upstreams"() {
setup:
def current = new CurrentMultistreamHolder(TestingCommons.emptyCaches())
def up1 = new EthereumUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api())
def up2 = new EthereumUpstreamMock("test2", Chain.ETHEREUM_CLASSIC, TestingCommons.api())
def up3 = new EthereumUpstreamMock("test3", Chain.ETHEREUM, TestingCommons.api())
def up1 = new EthereumRpcUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api())
def up2 = new EthereumRpcUpstreamMock("test2", Chain.ETHEREUM_CLASSIC, TestingCommons.api())
def up3 = new EthereumRpcUpstreamMock("test3", Chain.ETHEREUM, TestingCommons.api())
when:
current.update(new UpstreamChange(Chain.ETHEREUM, up1, UpstreamChange.ChangeType.ADDED))
current.update(new UpstreamChange(Chain.ETHEREUM_CLASSIC, up2, UpstreamChange.ChangeType.ADDED))
@@ -53,10 +53,10 @@ class CurrentMultistreamHolderSpec extends Specification {
def "remove upstream"() {
setup:
def current = new CurrentMultistreamHolder(TestingCommons.emptyCaches())
def up1 = new EthereumUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api())
def up2 = new EthereumUpstreamMock("test2", Chain.ETHEREUM_CLASSIC, TestingCommons.api())
def up3 = new EthereumUpstreamMock("test3", Chain.ETHEREUM, TestingCommons.api())
def up1_del = new EthereumUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api())
def up1 = new EthereumRpcUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api())
def up2 = new EthereumRpcUpstreamMock("test2", Chain.ETHEREUM_CLASSIC, TestingCommons.api())
def up3 = new EthereumRpcUpstreamMock("test3", Chain.ETHEREUM, TestingCommons.api())
def up1_del = new EthereumRpcUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api())
when:
current.update(new UpstreamChange(Chain.ETHEREUM, up1, UpstreamChange.ChangeType.ADDED))
current.update(new UpstreamChange(Chain.ETHEREUM_CLASSIC, up2, UpstreamChange.ChangeType.ADDED))
@@ -71,7 +71,7 @@ class CurrentMultistreamHolderSpec extends Specification {
def "available after adding"() {
setup:
def current = new CurrentMultistreamHolder(TestingCommons.emptyCaches())
def up1 = new EthereumUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api())
def up1 = new EthereumRpcUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api())
when:
def act = current.isAvailable(Chain.ETHEREUM)

View File

@@ -21,7 +21,7 @@ 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.EthereumUpstream
import io.emeraldpay.dshackle.upstream.ethereum.EthereumRpcUpstream
import io.emeraldpay.dshackle.upstream.ethereum.connectors.EthereumConnectorFactory
import io.emeraldpay.dshackle.upstream.forkchoice.MostWorkForkChoice
import io.emeraldpay.grpc.Chain
@@ -38,7 +38,7 @@ class FilteredApisSpec extends Specification {
def "Verifies labels"() {
setup:
def i = 0
List<EthereumUpstream> upstreams = [
List<EthereumRpcUpstream> upstreams = [
[test: "foo"],
[test: "bar"],
[test: "foo", test2: "baz"],
@@ -49,7 +49,7 @@ class FilteredApisSpec extends Specification {
create(_, _) >> TestingCommons.api().tap { it.id = "${i++}" }
}
def connectorFactory = new EthereumConnectorFactory(false, null, httpFactory, new MostWorkForkChoice())
new EthereumUpstream(
new EthereumRpcUpstream(
"test",
Chain.ETHEREUM,
new UpstreamsConfig.Options(),

View File

@@ -20,7 +20,7 @@ import io.emeraldpay.dshackle.cache.Caches
import io.emeraldpay.dshackle.config.UpstreamsConfig
import io.emeraldpay.dshackle.quorum.AlwaysQuorum
import io.emeraldpay.dshackle.reader.Reader
import io.emeraldpay.dshackle.test.EthereumUpstreamMock
import io.emeraldpay.dshackle.test.EthereumRpcUpstreamMock
import io.emeraldpay.dshackle.test.TestingCommons
import io.emeraldpay.dshackle.upstream.calls.DirectCallMethods
import io.emeraldpay.dshackle.upstream.ethereum.EthereumMultistream
@@ -38,8 +38,8 @@ class MultistreamSpec extends Specification {
def "Aggregates methods"() {
setup:
def up1 = new EthereumUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api(), new DirectCallMethods(["eth_test1", "eth_test2"]))
def up2 = new EthereumUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api(), new DirectCallMethods(["eth_test2", "eth_test3"]))
def up1 = new EthereumRpcUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api(), new DirectCallMethods(["eth_test1", "eth_test2"]))
def up2 = new EthereumRpcUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api(), new DirectCallMethods(["eth_test2", "eth_test3"]))
def aggr = new EthereumMultistream(Chain.ETHEREUM, [up1, up2], Caches.default())
when:
aggr.onUpstreamsUpdated()

View File

@@ -15,7 +15,7 @@
*/
package io.emeraldpay.dshackle.upstream.ethereum
import io.emeraldpay.dshackle.test.EthereumUpstreamMock
import io.emeraldpay.dshackle.test.EthereumRpcUpstreamMock
import io.emeraldpay.dshackle.test.ReaderMock
import io.emeraldpay.dshackle.upstream.ApiSource
import io.emeraldpay.dshackle.upstream.FilteredApis
@@ -47,7 +47,7 @@ class ERC20BalanceSpec extends Specification {
JsonRpcResponse.ok('"0x0000000000000000000000000000000000000000000000000000001f28d72868"')
)
EthereumUpstream upstream = new EthereumUpstreamMock(Chain.ETHEREUM, api)
EthereumRpcUpstream upstream = new EthereumRpcUpstreamMock(Chain.ETHEREUM, api)
ERC20Token token = new ERC20Token(Address.from("0x54EedeAC495271d0F6B175474E89094C44Da98b9"))
ERC20Balance query = new ERC20Balance()
@@ -73,7 +73,7 @@ class ERC20BalanceSpec extends Specification {
JsonRpcResponse.ok('"0x0000000000000000000000000000000000000000000000000000001f28d72868"')
)
EthereumUpstream upstream = new EthereumUpstreamMock(Chain.ETHEREUM, api)
EthereumRpcUpstream upstream = new EthereumRpcUpstreamMock(Chain.ETHEREUM, api)
ERC20Token token = new ERC20Token(Address.from("0x54EedeAC495271d0F6B175474E89094C44Da98b9"))
ERC20Balance query = new ERC20Balance()

View File

@@ -23,7 +23,7 @@ import io.emeraldpay.dshackle.data.BlockContainer
import io.emeraldpay.dshackle.data.BlockId
import io.emeraldpay.dshackle.data.TxContainer
import io.emeraldpay.dshackle.data.TxId
import io.emeraldpay.dshackle.test.EthereumUpstreamMock
import io.emeraldpay.dshackle.test.EthereumRpcUpstreamMock
import io.emeraldpay.dshackle.test.TestingCommons
import io.emeraldpay.dshackle.upstream.Multistream
import io.emeraldpay.dshackle.upstream.calls.CallMethods
@@ -203,7 +203,7 @@ class EthereumReaderSpec extends Specification {
api.answerOnce("eth_getBalance", ["0x70b91ff87a902b53dc6e2f6bda8bb9b330ccd30c", "latest"], "0x10")
// height 101 + 1 => 102 => 0x66
api.answerOnce("eth_getBalance", ["0x70b91ff87a902b53dc6e2f6bda8bb9b330ccd30c", "0x66"], "0xff")
EthereumUpstreamMock upstream = new EthereumUpstreamMock(Chain.ETHEREUM, api)
EthereumRpcUpstreamMock upstream = new EthereumRpcUpstreamMock(Chain.ETHEREUM, api)
def upstreams = TestingCommons.multistream(upstream)
def reader = new EthereumReader(upstreams, Caches.default(), calls)
reader.start()
@@ -241,7 +241,7 @@ class EthereumReaderSpec extends Specification {
api.answerOnce("eth_getTransactionReceipt", ["0xf85b826fdf98ee0f48f7db001be00472e63ceb056846f4ecac5f0c32878b8ab2"], [
transactionHash: "0xf85b826fdf98ee0f48f7db001be00472e63ceb056846f4ecac5f0c32878b8ab2"
])
EthereumUpstreamMock upstream = new EthereumUpstreamMock(Chain.ETHEREUM, api)
EthereumRpcUpstreamMock upstream = new EthereumRpcUpstreamMock(Chain.ETHEREUM, api)
def upstreams = TestingCommons.multistream(upstream)
def reader = new EthereumReader(upstreams, Caches.default(), calls)
reader.start()
@@ -257,7 +257,7 @@ class EthereumReaderSpec extends Specification {
def "Read receipt from cache if available"() {
setup:
def api = TestingCommons.api()
EthereumUpstreamMock upstream = new EthereumUpstreamMock(Chain.ETHEREUM, api)
EthereumRpcUpstreamMock upstream = new EthereumRpcUpstreamMock(Chain.ETHEREUM, api)
def upstreams = TestingCommons.multistream(upstream)
def receiptCache = Mock(ReceiptRedisCache) {
1 * it.read(TxId.from("0xf85b826fdf98ee0f48f7db001be00472e63ceb056846f4ecac5f0c32878b8ab2")) >>