diff --git a/src/main/kotlin/io/emeraldpay/dshackle/BlockchainType.kt b/src/main/kotlin/io/emeraldpay/dshackle/BlockchainType.kt index c518a6bd..3c26c0ee 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/BlockchainType.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/BlockchainType.kt @@ -15,7 +15,12 @@ enum class BlockchainType { chain == Chain.ETHEREUM || chain == Chain.TESTNET_SEPOLIA || chain == Chain.TESTNET_ARBITRUM || - chain == Chain.TESTNET_OPTIMISM + chain == Chain.TESTNET_OPTIMISM || + chain == Chain.ARBITRUM_NOVA || + chain == Chain.POLYGON_ZKEVM || + chain == Chain.TESTNET_POLYGON_ZKEVM || + chain == Chain.ZKSYNC || + chain == Chain.TESTNET_ZKSYNC ) { return EVM_POS } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/Chain.kt b/src/main/kotlin/io/emeraldpay/dshackle/Chain.kt index 1e182072..ff05e555 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/Chain.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/Chain.kt @@ -35,7 +35,20 @@ enum class Chain(val id: Int, val chainCode: String, val chainName: String) { "Arbitrum" ), OPTIMISM(1005, "OPTIMISM", "Optimism"), - BSC(1006, "BSC", "Binance Smart Chain"), // Testnets + BSC(1006, "BSC", "Binance Smart Chain"), + POLYGON_ZKEVM( + 1007, + "POLYGON_ZKEVM", + "Polygon ZK-EVM" + ), + ARBITRUM_NOVA( + 1008, + "ARBITRUM_NOVA", + "Arbitrum Nova" + ), + ZKSYNC(1009, "ZKSYNC", "ZkSync Era"), + + // Testnets TESTNET_MORDEN(10001, "MORDEN", "Morden Testnet"), TESTNET_KOVAN(10002, "KOVAN", "Kovan Testnet"), TESTNET_BITCOIN( @@ -56,7 +69,17 @@ enum class Chain(val id: Int, val chainCode: String, val chainName: String) { "ARBITRUM_TESTNET", "Arbitrum Testnet" ), - TESTNET_OPTIMISM(10010, "OPTIMISM_TESTNET", "Optimism Testnet"); + TESTNET_OPTIMISM(10010, "OPTIMISM_TESTNET", "Optimism Testnet"), + TESTNET_POLYGON_ZKEVM( + 10011, + "POLYGON_ZKEVM_TESTNET", + "Polygon ZK-EVM Testnet" + ), + TESTNET_ZKSYNC( + 10012, + "ZKS_TESTNET", + "ZkSync Testnet" + ); companion object { fun byId(id: Int): Chain { diff --git a/src/main/kotlin/io/emeraldpay/dshackle/Global.kt b/src/main/kotlin/io/emeraldpay/dshackle/Global.kt index bd435163..62981366 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/Global.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/Global.kt @@ -71,6 +71,11 @@ class Global { "sepolia-testnet" to Chain.TESTNET_SEPOLIA, "optimism-testnet" to Chain.TESTNET_OPTIMISM, "arbitrum-testnet" to Chain.TESTNET_ARBITRUM, + "arbitrum-nova" to Chain.ARBITRUM_NOVA, + "polygon-zkevm" to Chain.POLYGON_ZKEVM, + "polygon-zkevm-testnet" to Chain.TESTNET_POLYGON_ZKEVM, + "zksync" to Chain.ZKSYNC, + "zksync-testnet" to Chain.TESTNET_ZKSYNC, ) fun chainById(id: String?): Chain { diff --git a/src/main/kotlin/io/emeraldpay/dshackle/config/ChainsConfigReader.kt b/src/main/kotlin/io/emeraldpay/dshackle/config/ChainsConfigReader.kt index 8d1ac411..bddff0a4 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/config/ChainsConfigReader.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/config/ChainsConfigReader.kt @@ -14,7 +14,8 @@ class ChainsConfigReader( override fun read(input: MappingNode?): ChainsConfig { val default = readInternal(defaultConfig) val current = readInternal(input) - return default.patch(current) + val res = default.patch(current) + return res } fun readInternal(input: InputStream): ChainsConfig { diff --git a/src/main/kotlin/io/emeraldpay/dshackle/config/UpstreamsConfig.kt b/src/main/kotlin/io/emeraldpay/dshackle/config/UpstreamsConfig.kt index 785c0f65..7fcbb683 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/config/UpstreamsConfig.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/config/UpstreamsConfig.kt @@ -90,7 +90,6 @@ open class UpstreamsConfig { fun getDefaults(): PartialOptions { val options = PartialOptions() options.minPeers = 1 - options.disableValidation = false return options } } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/startup/ConfiguredUpstreams.kt b/src/main/kotlin/io/emeraldpay/dshackle/startup/ConfiguredUpstreams.kt index 20c96e8f..d613d3fb 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/startup/ConfiguredUpstreams.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/startup/ConfiguredUpstreams.kt @@ -230,7 +230,8 @@ open class ConfiguredUpstreams( config.id!!, hash, chain, - options, config.role, + options, + config.role, methods, QuorumForLabels.QuorumItem(1, config.labels), connectorFactory, diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/Multistream.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/Multistream.kt index d436c57e..d93a152b 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/Multistream.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/Multistream.kt @@ -263,12 +263,12 @@ abstract class Multistream( } override fun start() { - val repeated = Flux.interval(Duration.ofSeconds(30)) + val repeated = Flux.interval(Duration.ofSeconds(3)) val whenChanged = observeStatus() .distinctUntilChanged() subscription = Flux.merge(repeated, whenChanged) // print status _change_ every 15 seconds, at most; otherwise prints it on interval of 30 seconds - .sample(Duration.ofSeconds(15)) + .sample(Duration.ofSeconds(3)) .subscribe { printStatus() } observeUpstreamsStatuses() 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 53308d90..e3b71edf 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/DefaultEthereumMethods.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/DefaultEthereumMethods.kt @@ -172,7 +172,7 @@ class DefaultEthereumMethods( private fun getChainSpecificMethods(chain: Chain): List { return when (chain) { - Chain.OPTIMISM -> listOf( + Chain.OPTIMISM, Chain.TESTNET_OPTIMISM -> listOf( "rollup_gasPrices" ) Chain.POLYGON -> listOf( @@ -183,6 +183,37 @@ class DefaultEthereumMethods( "bor_getSignersAtHash", "eth_getRootHash" ) + Chain.POLYGON_ZKEVM, Chain.TESTNET_POLYGON_ZKEVM -> listOf( + "zkevm_consolidatedBlockNumber", + "zkevm_isBlockConsolidated", + "zkevm_isBlockVirtualized", + "zkevm_batchNumberByBlockNumber", + "zkevm_batchNumber", + "zkevm_virtualBatchNumber", + "zkevm_verifiedBatchNumber", + "zkevm_getBatchByNumber", + "zkevm_getBroadcastURI" + ) + Chain.ZKSYNC, Chain.TESTNET_ZKSYNC -> listOf( + "zks_estimateFee", + "zks_estimateGasL1ToL2", + "zks_getAllAccountBalances", + "zks_getBlockDetails", + "zks_getBridgeContracts", + "zks_getBytecodeByHash", + "zks_getConfirmedTokens", + "zks_getL1BatchBlockRange", + "zks_getL1BatchDetails", + "zks_getL2ToL1LogProof", + "zks_getL2ToL1MsgProof", + "zks_getMainContract", + "zks_getRawBlockTransactions", + "zks_getTestnetPaymaster", + "zks_getTokenPrice", + "zks_getTransactionDetails", + "zks_L1BatchNumber", + "zks_L1ChainId" + ) else -> emptyList() } } @@ -260,6 +291,26 @@ class DefaultEthereumMethods( "\"420\"" } + Chain.ARBITRUM_NOVA == chain -> { + "\"42170\"" + } + + Chain.POLYGON_ZKEVM == chain -> { + "\"1101\"" + } + + Chain.TESTNET_POLYGON_ZKEVM == chain -> { + "\"1442\"" + } + + Chain.ZKSYNC == chain -> { + "\"324\"" + } + + Chain.TESTNET_ZKSYNC == chain -> { + "\"280\"" + } + else -> throw RpcException(-32602, "Invalid chain") } } @@ -318,6 +369,26 @@ class DefaultEthereumMethods( "\"0x1A4\"" } + Chain.ARBITRUM_NOVA == chain -> { + "\"0xa4ba\"" + } + + Chain.POLYGON_ZKEVM == chain -> { + "\"0x44d\"" + } + + Chain.TESTNET_POLYGON_ZKEVM == chain -> { + "\"0x5a2\"" + } + + Chain.ZKSYNC == chain -> { + "\"0x144\"" + } + + Chain.TESTNET_ZKSYNC == chain -> { + "\"0x118\"" + } + else -> throw RpcException(-32602, "Invalid chain") } } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumMultistream.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumMultistream.kt index 7d035f15..7e9ac2ef 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumMultistream.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumMultistream.kt @@ -65,14 +65,24 @@ open class EthereumMultistream( private val reader: EthereumCachingReader = EthereumCachingReader(this, this.caches, getMethodsFactory(), tracer) private var subscribe = EthereumEgressSubscription(this, headScheduler, NoPendingTxes()) - private val supportsEIP1559 = when (chain) { + private val supportsEIP1559set = setOf( Chain.ETHEREUM, Chain.TESTNET_ROPSTEN, - Chain.TESTNET_GOERLI, Chain.TESTNET_RINKEBY, - Chain.TESTNET_SEPOLIA, Chain.ARBITRUM, - Chain.OPTIMISM, Chain.TESTNET_ARBITRUM, - Chain.TESTNET_OPTIMISM -> true - else -> false - } + Chain.TESTNET_GOERLI, + Chain.TESTNET_RINKEBY, + Chain.TESTNET_SEPOLIA, + Chain.ARBITRUM, + Chain.OPTIMISM, + Chain.TESTNET_ARBITRUM, + Chain.TESTNET_OPTIMISM, + Chain.POLYGON_ZKEVM, + Chain.TESTNET_POLYGON_ZKEVM, + Chain.ZKSYNC, + Chain.TESTNET_ZKSYNC, + Chain.ARBITRUM_NOVA + ) + + private val supportsEIP1559 = supportsEIP1559set.contains(chain) + private val feeEstimation = if (supportsEIP1559) EthereumPriorityFees(this, reader, 256) else EthereumLegacyFees(this, reader, 256) diff --git a/src/main/resources/chains.yaml b/src/main/resources/chains.yaml index 6f7df75c..67d32ac6 100644 --- a/src/main/resources/chains.yaml +++ b/src/main/resources/chains.yaml @@ -38,3 +38,33 @@ chain-settings: lags: syncing: 20 lagging: 10 + - id: arbitrum-nova + options: + disable-validation: true + lags: + syncing: 20 + lagging: 10 + - id: polygon-zkevm + options: + disable-validation: true + lags: + syncing: 20 + lagging: 10 + - id: polygon-zkevm-testnet + options: + disable-validation: true + lags: + syncing: 20 + lagging: 10 + - id: zksync + options: + disable-validation: true + lags: + syncing: 20 + lagging: 10 + - id: zksync-testnet + options: + disable-validation: true + lags: + syncing: 20 + lagging: 10