solution: add support for Polygon/Matic
This commit is contained in:
@@ -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}"
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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<BlockchainOuterClass.TxStatus> {
|
||||
|
||||
@@ -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<BlockchainOuterClass.AddressBalance> {
|
||||
|
||||
@@ -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<BlockchainOuterClass.AddressBalance> {
|
||||
|
||||
@@ -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<BlockchainOuterClass.TxStatus> {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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\""
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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]
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user