From 802d1c8eb8314a0e961b4fcb49401d8a7a4ea12b Mon Sep 17 00:00:00 2001 From: Chase Wright Date: Wed, 11 Aug 2021 22:25:33 -0500 Subject: [PATCH] solution: add support for Polygon/Matic --- build.gradle | 2 +- proto/common.proto | 17 ++++--- .../io/emeraldpay/dshackle/BlockchainType.kt | 48 ------------------- .../dshackle/config/TokensConfig.kt | 4 +- .../io/emeraldpay/dshackle/rpc/StreamHead.kt | 1 - .../dshackle/rpc/TrackBitcoinAddress.kt | 4 +- .../emeraldpay/dshackle/rpc/TrackBitcoinTx.kt | 4 +- .../dshackle/rpc/TrackERC20Address.kt | 4 +- .../dshackle/rpc/TrackEthereumAddress.kt | 4 +- .../dshackle/rpc/TrackEthereumTx.kt | 4 +- .../dshackle/startup/ConfiguredUpstreams.kt | 6 ++- .../upstream/CurrentMultistreamHolder.kt | 6 +-- .../upstream/calls/DefaultEthereumMethods.kt | 6 +++ .../dshackle/upstream/grpc/GrpcUpstreams.kt | 4 +- .../dshackle/BlockchainTypeSpec.groovy | 37 -------------- .../test/MultistreamHolderMock.groovy | 6 +-- 16 files changed, 42 insertions(+), 115 deletions(-) delete mode 100644 src/main/kotlin/io/emeraldpay/dshackle/BlockchainType.kt delete mode 100644 src/test/groovy/io/emeraldpay/dshackle/BlockchainTypeSpec.groovy diff --git a/build.gradle b/build.gradle index e0dfb311..4350b19e 100644 --- a/build.gradle +++ b/build.gradle @@ -61,7 +61,7 @@ configurations { } dependencies { - implementation "io.emeraldpay:emerald-api:0.9.2" + implementation "io.emeraldpay:emerald-api:0.9.4" implementation "io.grpc:grpc-protobuf:${grpcVersion}" implementation "io.grpc:grpc-stub:${grpcVersion}" diff --git a/proto/common.proto b/proto/common.proto index 06388830..5d299d7e 100644 --- a/proto/common.proto +++ b/proto/common.proto @@ -10,22 +10,27 @@ enum ChainRef { CHAIN_UNSPECIFIED = 0; CHAIN_BITCOIN = 1; - CHAIN_GRIN = 2; + // CHAIN_GRIN = 2; CHAIN_ETHEREUM = 100; CHAIN_ETHEREUM_CLASSIC = 101; + CHAIN_FANTOM = 102; // Fantom, https://fantom.foundation/ - // Sidechains and state channels - CHAIN_LIGHTNING = 1001; + // Sidechains and state channels start with 1_000 + // CHAIN_LIGHTNING = 1001; + CHAIN_MATIC = 1002; // Matic PoS Ethereum sidechain based on Polygon + CHAIN_RSK = 1003; // RSK sidechain, https://www.rsk.co/ - // Testnets + // Testnets start with 10_000 CHAIN_MORDEN = 10001; CHAIN_KOVAN = 10002; CHAIN_TESTNET_BITCOIN = 10003; - CHAIN_FLOONET = 10004; + // CHAIN_FLOONET = 10004; CHAIN_GOERLI = 10005; + CHAIN_ROPSTEN = 10006; + CHAIN_RINKEBY = 10007; - // Non-standard starts from 50000 + // Non-standard starts from 20_000 } message SingleAddress { diff --git a/src/main/kotlin/io/emeraldpay/dshackle/BlockchainType.kt b/src/main/kotlin/io/emeraldpay/dshackle/BlockchainType.kt deleted file mode 100644 index 0dc1207b..00000000 --- a/src/main/kotlin/io/emeraldpay/dshackle/BlockchainType.kt +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright (c) 2020 EmeraldPay, Inc - * Copyright (c) 2020 ETCDEV GmbH - * - * 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 - -import io.emeraldpay.grpc.Chain - -/** - * Type of the blockchain, architecture-wise - */ -enum class BlockchainType { - - ETHEREUM, - BITCOIN, - OTHER; - - companion object { - @JvmStatic - fun fromBlockchain(blockchain: Chain): BlockchainType { - if (blockchain == Chain.ETHEREUM - || blockchain == Chain.ETHEREUM_CLASSIC - || blockchain == Chain.TESTNET_KOVAN - || blockchain == Chain.TESTNET_ROPSTEN - || blockchain == Chain.TESTNET_RINKEBY - || blockchain == Chain.TESTNET_MORDEN - || blockchain == Chain.TESTNET_GOERLI) { - return ETHEREUM - } - if (blockchain == Chain.BITCOIN || blockchain == Chain.TESTNET_BITCOIN) { - return BITCOIN - } - return OTHER - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/io/emeraldpay/dshackle/config/TokensConfig.kt b/src/main/kotlin/io/emeraldpay/dshackle/config/TokensConfig.kt index d9bd5e95..c43f8942 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/config/TokensConfig.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/config/TokensConfig.kt @@ -15,7 +15,7 @@ */ package io.emeraldpay.dshackle.config -import io.emeraldpay.dshackle.BlockchainType +import io.emeraldpay.grpc.BlockchainType import io.emeraldpay.grpc.Chain import io.infinitape.etherjar.domain.Address @@ -41,7 +41,7 @@ class TokensConfig( type == null -> type address.isNullOrBlank() -> "address" blockchain != null - && BlockchainType.fromBlockchain(blockchain!!) == BlockchainType.ETHEREUM + && BlockchainType.from(blockchain!!) == BlockchainType.ETHEREUM && !Address.isValidAddress(address) -> "address" else -> null } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/rpc/StreamHead.kt b/src/main/kotlin/io/emeraldpay/dshackle/rpc/StreamHead.kt index 7905b3dd..f60cb81a 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/rpc/StreamHead.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/rpc/StreamHead.kt @@ -19,7 +19,6 @@ package io.emeraldpay.dshackle.rpc import com.google.protobuf.ByteString import io.emeraldpay.api.proto.BlockchainOuterClass import io.emeraldpay.api.proto.Common -import io.emeraldpay.dshackle.BlockchainType import io.emeraldpay.dshackle.data.BlockContainer import io.emeraldpay.dshackle.upstream.MultistreamHolder import io.emeraldpay.grpc.Chain diff --git a/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackBitcoinAddress.kt b/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackBitcoinAddress.kt index ca76ccc4..798ab7f7 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackBitcoinAddress.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackBitcoinAddress.kt @@ -18,7 +18,7 @@ package io.emeraldpay.dshackle.rpc import io.emeraldpay.api.proto.BlockchainOuterClass import io.emeraldpay.api.proto.Common import io.emeraldpay.api.proto.ReactorBlockchainGrpc -import io.emeraldpay.dshackle.BlockchainType +import io.emeraldpay.grpc.BlockchainType import io.emeraldpay.dshackle.Defaults import io.emeraldpay.dshackle.SilentException import io.emeraldpay.dshackle.upstream.Capability @@ -53,7 +53,7 @@ class TrackBitcoinAddress( override fun isSupported(chain: Chain, asset: String): Boolean { return (asset == "bitcoin" || asset == "btc" || asset == "satoshi") - && BlockchainType.fromBlockchain(chain) == BlockchainType.BITCOIN && multistreamHolder.isAvailable(chain) + && BlockchainType.from(chain) == BlockchainType.BITCOIN && multistreamHolder.isAvailable(chain) } /** diff --git a/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackBitcoinTx.kt b/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackBitcoinTx.kt index 8199ff41..ca142b50 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackBitcoinTx.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackBitcoinTx.kt @@ -18,7 +18,7 @@ package io.emeraldpay.dshackle.rpc import com.google.protobuf.ByteString import io.emeraldpay.api.proto.BlockchainOuterClass import io.emeraldpay.api.proto.Common -import io.emeraldpay.dshackle.BlockchainType +import io.emeraldpay.grpc.BlockchainType import io.emeraldpay.dshackle.SilentException import io.emeraldpay.dshackle.upstream.MultistreamHolder import io.emeraldpay.dshackle.upstream.bitcoin.BitcoinMultistream @@ -45,7 +45,7 @@ class TrackBitcoinTx( } override fun isSupported(chain: Chain): Boolean { - return BlockchainType.fromBlockchain(chain) == BlockchainType.BITCOIN && multistreamHolder.isAvailable(chain) + return BlockchainType.from(chain) == BlockchainType.BITCOIN && multistreamHolder.isAvailable(chain) } override fun subscribe(request: BlockchainOuterClass.TxStatusRequest): Flux { diff --git a/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackERC20Address.kt b/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackERC20Address.kt index 97349828..07533f3e 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackERC20Address.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackERC20Address.kt @@ -2,7 +2,7 @@ package io.emeraldpay.dshackle.rpc import io.emeraldpay.api.proto.BlockchainOuterClass import io.emeraldpay.api.proto.Common -import io.emeraldpay.dshackle.BlockchainType +import io.emeraldpay.grpc.BlockchainType import io.emeraldpay.dshackle.SilentException import io.emeraldpay.dshackle.config.TokensConfig import io.emeraldpay.dshackle.upstream.Head @@ -54,7 +54,7 @@ class TrackERC20Address( override fun isSupported(chain: Chain, asset: String): Boolean { return tokens.containsKey(TokenId(chain, asset.toLowerCase())) && - BlockchainType.fromBlockchain(chain) == BlockchainType.ETHEREUM && multistreamHolder.isAvailable(chain) + BlockchainType.from(chain) == BlockchainType.ETHEREUM && multistreamHolder.isAvailable(chain) } override fun getBalance(request: BlockchainOuterClass.BalanceRequest): Flux { diff --git a/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackEthereumAddress.kt b/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackEthereumAddress.kt index c2e37e1d..588de8e9 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackEthereumAddress.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackEthereumAddress.kt @@ -18,7 +18,7 @@ package io.emeraldpay.dshackle.rpc import io.emeraldpay.api.proto.BlockchainOuterClass import io.emeraldpay.api.proto.Common -import io.emeraldpay.dshackle.BlockchainType +import io.emeraldpay.grpc.BlockchainType import io.emeraldpay.dshackle.Defaults import io.emeraldpay.dshackle.SilentException import io.emeraldpay.dshackle.upstream.MultistreamHolder @@ -42,7 +42,7 @@ class TrackEthereumAddress( override fun isSupported(chain: Chain, asset: String): Boolean { return asset == "ether" && - BlockchainType.fromBlockchain(chain) == BlockchainType.ETHEREUM && multistreamHolder.isAvailable(chain) + BlockchainType.from(chain) == BlockchainType.ETHEREUM && multistreamHolder.isAvailable(chain) } override fun getBalance(request: BlockchainOuterClass.BalanceRequest): Flux { diff --git a/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackEthereumTx.kt b/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackEthereumTx.kt index e6d45165..8b02ec78 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackEthereumTx.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackEthereumTx.kt @@ -19,7 +19,7 @@ package io.emeraldpay.dshackle.rpc import com.google.protobuf.ByteString import io.emeraldpay.api.proto.BlockchainOuterClass import io.emeraldpay.api.proto.Common -import io.emeraldpay.dshackle.BlockchainType +import io.emeraldpay.grpc.BlockchainType import io.emeraldpay.dshackle.SilentException import io.emeraldpay.dshackle.data.BlockContainer import io.emeraldpay.dshackle.data.TxId @@ -63,7 +63,7 @@ class TrackEthereumTx( private val log = LoggerFactory.getLogger(TrackEthereumTx::class.java) override fun isSupported(chain: Chain): Boolean { - return BlockchainType.fromBlockchain(chain) == BlockchainType.ETHEREUM && multistreamHolder.isAvailable(chain) + return BlockchainType.from(chain) == BlockchainType.ETHEREUM && multistreamHolder.isAvailable(chain) } override fun subscribe(request: BlockchainOuterClass.TxStatusRequest): Flux { diff --git a/src/main/kotlin/io/emeraldpay/dshackle/startup/ConfiguredUpstreams.kt b/src/main/kotlin/io/emeraldpay/dshackle/startup/ConfiguredUpstreams.kt index b7a52ffe..488efe06 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/startup/ConfiguredUpstreams.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/startup/ConfiguredUpstreams.kt @@ -16,7 +16,7 @@ */ package io.emeraldpay.dshackle.startup -import io.emeraldpay.dshackle.BlockchainType +import io.emeraldpay.grpc.BlockchainType import io.emeraldpay.dshackle.FileResolver import io.emeraldpay.dshackle.cache.CachesFactory import io.emeraldpay.dshackle.config.UpstreamsConfig @@ -62,6 +62,8 @@ open class ConfiguredUpstreams( "ethereum" to Chain.ETHEREUM, "ethereum-classic" to Chain.ETHEREUM_CLASSIC, "eth" to Chain.ETHEREUM, + "polygon" to Chain.MATIC, + "matic" to Chain.MATIC, "etc" to Chain.ETHEREUM_CLASSIC, "morden" to Chain.TESTNET_MORDEN, "kovan" to Chain.TESTNET_KOVAN, @@ -93,7 +95,7 @@ open class ConfiguredUpstreams( } val options = (up.options ?: UpstreamsConfig.Options()) .merge(defaultOptions[chain] ?: UpstreamsConfig.Options.getDefaults()) - when (BlockchainType.fromBlockchain(chain)) { + when (BlockchainType.from(chain)) { BlockchainType.ETHEREUM -> { buildEthereumUpstream(up.cast(UpstreamsConfig.EthereumConnection::class.java), chain, options) } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/CurrentMultistreamHolder.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/CurrentMultistreamHolder.kt index d6779846..9271c017 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/CurrentMultistreamHolder.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/CurrentMultistreamHolder.kt @@ -16,7 +16,7 @@ */ package io.emeraldpay.dshackle.upstream -import io.emeraldpay.dshackle.BlockchainType +import io.emeraldpay.grpc.BlockchainType import io.emeraldpay.dshackle.cache.CachesEnabled import io.emeraldpay.dshackle.cache.CachesFactory import io.emeraldpay.dshackle.startup.UpstreamChange @@ -58,7 +58,7 @@ open class CurrentMultistreamHolder( log.debug("Upstream update: ${change.type} ${change.chain} via ${change.upstream.getId()}") val chain = change.chain try { - when (BlockchainType.fromBlockchain(chain)) { + when (BlockchainType.from(chain)) { BlockchainType.ETHEREUM -> { val up = change.upstream.cast(EthereumUpstream::class.java) val current = chainMapping[chain] as Multistream? @@ -138,7 +138,7 @@ open class CurrentMultistreamHolder( } fun setupDefaultMethods(chain: Chain): CallMethods { - val created = when (BlockchainType.fromBlockchain(chain)) { + val created = when (BlockchainType.from(chain)) { BlockchainType.ETHEREUM -> DefaultEthereumMethods(chain) BlockchainType.BITCOIN -> DefaultBitcoinMethods() else -> throw IllegalStateException("Unsupported chain: $chain") diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/DefaultEthereumMethods.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/DefaultEthereumMethods.kt index f21e0e9c..cc88d4d2 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/DefaultEthereumMethods.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/DefaultEthereumMethods.kt @@ -119,6 +119,9 @@ class DefaultEthereumMethods( Chain.ETHEREUM_CLASSIC == chain -> { "\"1\"" } + Chain.MATIC == chain -> { + "\"137\"" + } Chain.TESTNET_MORDEN == chain -> { "\"2\"" } @@ -142,6 +145,9 @@ class DefaultEthereumMethods( Chain.ETHEREUM == chain -> { "\"0x1\"" } + Chain.MATIC == chain -> { + "\"0x89\"" + } Chain.TESTNET_ROPSTEN == chain -> { "\"0x3\"" } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/grpc/GrpcUpstreams.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/grpc/GrpcUpstreams.kt index fc08e9db..a609799a 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/grpc/GrpcUpstreams.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/grpc/GrpcUpstreams.kt @@ -18,7 +18,7 @@ package io.emeraldpay.dshackle.upstream.grpc import io.emeraldpay.api.proto.BlockchainOuterClass import io.emeraldpay.api.proto.ReactorBlockchainGrpc -import io.emeraldpay.dshackle.BlockchainType +import io.emeraldpay.grpc.BlockchainType import io.emeraldpay.dshackle.Defaults import io.emeraldpay.dshackle.FileResolver import io.emeraldpay.dshackle.config.AuthConfig @@ -179,7 +179,7 @@ class GrpcUpstreams( .register(Metrics.globalRegistry) ) - val blockchainType = BlockchainType.fromBlockchain(chain) + val blockchainType = BlockchainType.from(chain) if (blockchainType == BlockchainType.ETHEREUM) { return getOrCreateEthereum(chain, metrics) } else if (blockchainType == BlockchainType.BITCOIN) { diff --git a/src/test/groovy/io/emeraldpay/dshackle/BlockchainTypeSpec.groovy b/src/test/groovy/io/emeraldpay/dshackle/BlockchainTypeSpec.groovy deleted file mode 100644 index 77c1e7e6..00000000 --- a/src/test/groovy/io/emeraldpay/dshackle/BlockchainTypeSpec.groovy +++ /dev/null @@ -1,37 +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 - -import io.emeraldpay.grpc.Chain -import spock.lang.Specification - -class BlockchainTypeSpec extends Specification { - - def "Correct type for ethereum"() { - expect: - BlockchainType.fromBlockchain(chain) == BlockchainType.ETHEREUM - where: - chain << [Chain.ETHEREUM, Chain.ETHEREUM_CLASSIC, Chain.TESTNET_KOVAN, Chain.TESTNET_GOERLI, Chain.TESTNET_MORDEN, Chain.TESTNET_RINKEBY, Chain.TESTNET_ROPSTEN] - } - - def "Correct type for bitcoin"() { - expect: - BlockchainType.fromBlockchain(chain) == BlockchainType.BITCOIN - where: - chain << [Chain.BITCOIN, Chain.TESTNET_BITCOIN] - } - -} diff --git a/src/test/groovy/io/emeraldpay/dshackle/test/MultistreamHolderMock.groovy b/src/test/groovy/io/emeraldpay/dshackle/test/MultistreamHolderMock.groovy index a98fb797..994c995c 100644 --- a/src/test/groovy/io/emeraldpay/dshackle/test/MultistreamHolderMock.groovy +++ b/src/test/groovy/io/emeraldpay/dshackle/test/MultistreamHolderMock.groovy @@ -17,7 +17,6 @@ package io.emeraldpay.dshackle.test -import io.emeraldpay.dshackle.BlockchainType import io.emeraldpay.dshackle.cache.Caches import io.emeraldpay.dshackle.upstream.Head import io.emeraldpay.dshackle.upstream.Multistream @@ -30,6 +29,7 @@ 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.grpc.BlockchainType import io.emeraldpay.grpc.Chain import org.jetbrains.annotations.NotNull import reactor.core.publisher.Flux @@ -45,7 +45,7 @@ class MultistreamHolderMock implements MultistreamHolder { Multistream addUpstream(@NotNull Chain chain, @NotNull Upstream up) { if (!upstreams.containsKey(chain)) { - if (BlockchainType.fromBlockchain(chain) == BlockchainType.ETHEREUM) { + if (BlockchainType.from(chain) == BlockchainType.ETHEREUM) { if (up instanceof EthereumMultistream) { upstreams[chain] = up } else if (up instanceof EthereumUpstream) { @@ -54,7 +54,7 @@ class MultistreamHolderMock implements MultistreamHolder { throw new IllegalArgumentException("Unsupported upstream type ${up.class}") } upstreams[chain].start() - } else if (BlockchainType.fromBlockchain(chain) == BlockchainType.BITCOIN) { + } else if (BlockchainType.from(chain) == BlockchainType.BITCOIN) { if (up instanceof BitcoinMultistream) { upstreams[chain] = up } else if (up instanceof BitcoinRpcUpstream) {