support evm networks: Arbitrum, Optimism, Binance Smart Chain
This commit is contained in:
@@ -44,8 +44,15 @@ class Global {
|
||||
"ethereum" to Chain.ETHEREUM,
|
||||
"ethereum-classic" to Chain.ETHEREUM_CLASSIC,
|
||||
"eth" to Chain.ETHEREUM,
|
||||
"polygon" to Chain.MATIC,
|
||||
"matic" to Chain.MATIC,
|
||||
"polygon" to Chain.POLYGON,
|
||||
"matic" to Chain.POLYGON,
|
||||
"arbitrum" to Chain.ARBITRUM,
|
||||
"arb" to Chain.ARBITRUM,
|
||||
"optimism" to Chain.OPTIMISM,
|
||||
"binance" to Chain.BSC,
|
||||
"bsc" to Chain.BSC,
|
||||
"bnb-smart-chan" to Chain.BSC,
|
||||
"etc" to Chain.ETHEREUM_CLASSIC,
|
||||
"etc" to Chain.ETHEREUM_CLASSIC,
|
||||
"morden" to Chain.TESTNET_MORDEN,
|
||||
"kovan" to Chain.TESTNET_KOVAN,
|
||||
|
||||
@@ -41,7 +41,7 @@ class TokensConfig(
|
||||
type == null -> type
|
||||
address.isNullOrBlank() -> "address"
|
||||
blockchain != null &&
|
||||
(BlockchainType.from(blockchain!!) == BlockchainType.ETHEREUM_POS || BlockchainType.from(blockchain!!) == BlockchainType.ETHEREUM) &&
|
||||
(BlockchainType.from(blockchain!!) == BlockchainType.EVM_POS || BlockchainType.from(blockchain!!) == BlockchainType.EVM_POW) &&
|
||||
!Address.isValidAddress(address) -> "address"
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import io.emeraldpay.dshackle.upstream.Multistream
|
||||
import io.emeraldpay.dshackle.upstream.MultistreamHolder
|
||||
import io.emeraldpay.dshackle.upstream.Selector
|
||||
import io.emeraldpay.dshackle.upstream.calls.EthereumCallSelector
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.EthereumMultistream
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.EthereumPosMultiStream
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcError
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcException
|
||||
@@ -66,14 +67,16 @@ open class NativeCall(
|
||||
private val ethereumCallSelectors = EnumMap<Chain, EthereumCallSelector>(Chain::class.java)
|
||||
|
||||
init {
|
||||
val casting = mapOf(
|
||||
BlockchainType.EVM_POS to EthereumPosMultiStream::class.java,
|
||||
BlockchainType.EVM_POW to EthereumMultistream::class.java,
|
||||
)
|
||||
|
||||
multistreamHolder.observeChains().subscribe { chain ->
|
||||
if ((BlockchainType.from(chain) == BlockchainType.ETHEREUM_POS || BlockchainType.from(chain) == BlockchainType.ETHEREUM) && !ethereumCallSelectors.containsKey(
|
||||
chain
|
||||
)
|
||||
) {
|
||||
casting[BlockchainType.from(chain)]?.let { cast ->
|
||||
multistreamHolder.getUpstream(chain)?.let { up ->
|
||||
val reader = up.cast(EthereumPosMultiStream::class.java).getReader()
|
||||
ethereumCallSelectors[chain] = EthereumCallSelector(reader.heightByHash())
|
||||
val reader = up.cast(cast).getReader()
|
||||
ethereumCallSelectors.putIfAbsent(chain, EthereumCallSelector(reader.heightByHash()))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -212,7 +215,7 @@ open class NativeCall(
|
||||
}
|
||||
// for ethereum the actual block needed for the call may be specified in the call parameters
|
||||
val callSpecificMatcher: Mono<Selector.Matcher> =
|
||||
if (BlockchainType.from(upstream.chain) == BlockchainType.ETHEREUM_POS || BlockchainType.from(upstream.chain) == BlockchainType.ETHEREUM) {
|
||||
if (BlockchainType.from(upstream.chain) == BlockchainType.EVM_POS || BlockchainType.from(upstream.chain) == BlockchainType.EVM_POW) {
|
||||
ethereumCallSelectors[chain]?.getMatcher(method, params, upstream.getHead())
|
||||
} else {
|
||||
null
|
||||
|
||||
@@ -57,7 +57,7 @@ open class NativeSubscribe(
|
||||
|
||||
fun start(request: BlockchainOuterClass.NativeSubscribeRequest): Publisher<ResponseHolder> {
|
||||
val chain = Chain.byId(request.chainValue)
|
||||
if (BlockchainType.from(chain) != BlockchainType.ETHEREUM_POS && BlockchainType.from(chain) != BlockchainType.ETHEREUM) {
|
||||
if (BlockchainType.from(chain) != BlockchainType.EVM_POS && BlockchainType.from(chain) != BlockchainType.EVM_POW) {
|
||||
return Mono.error(UnsupportedOperationException("Native subscribe is not supported for ${chain.chainCode}"))
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ class TrackERC20Address(
|
||||
|
||||
override fun isSupported(chain: Chain, asset: String): Boolean {
|
||||
return tokens.containsKey(TokenId(chain, asset.lowercase(Locale.getDefault()))) &&
|
||||
(BlockchainType.from(chain) == BlockchainType.ETHEREUM_POS || BlockchainType.from(chain) == BlockchainType.ETHEREUM) && multistreamHolder.isAvailable(chain)
|
||||
(BlockchainType.from(chain) == BlockchainType.EVM_POS || BlockchainType.from(chain) == BlockchainType.EVM_POW) && multistreamHolder.isAvailable(chain)
|
||||
}
|
||||
|
||||
override fun getBalance(request: BlockchainOuterClass.BalanceRequest): Flux<BlockchainOuterClass.AddressBalance> {
|
||||
|
||||
@@ -43,7 +43,7 @@ class TrackEthereumAddress(
|
||||
|
||||
override fun isSupported(chain: Chain, asset: String): Boolean {
|
||||
return asset == "ether" &&
|
||||
(BlockchainType.from(chain) == BlockchainType.ETHEREUM_POS || BlockchainType.from(chain) == BlockchainType.ETHEREUM) && multistreamHolder.isAvailable(chain)
|
||||
(BlockchainType.from(chain) == BlockchainType.EVM_POS || BlockchainType.from(chain) == BlockchainType.EVM_POW) && multistreamHolder.isAvailable(chain)
|
||||
}
|
||||
|
||||
override fun getBalance(request: BlockchainOuterClass.BalanceRequest): Flux<BlockchainOuterClass.AddressBalance> {
|
||||
|
||||
@@ -62,7 +62,7 @@ class TrackEthereumTx(
|
||||
private val log = LoggerFactory.getLogger(TrackEthereumTx::class.java)
|
||||
|
||||
override fun isSupported(chain: Chain): Boolean {
|
||||
return (BlockchainType.from(chain) == BlockchainType.ETHEREUM_POS || BlockchainType.from(chain) == BlockchainType.ETHEREUM) && multistreamHolder.isAvailable(chain)
|
||||
return (BlockchainType.from(chain) == BlockchainType.EVM_POS || BlockchainType.from(chain) == BlockchainType.EVM_POW) && multistreamHolder.isAvailable(chain)
|
||||
}
|
||||
|
||||
override fun subscribe(request: BlockchainOuterClass.TxStatusRequest): Flux<BlockchainOuterClass.TxStatus> {
|
||||
|
||||
@@ -87,13 +87,13 @@ open class ConfiguredUpstreams(
|
||||
val options = (up.options ?: UpstreamsConfig.Options())
|
||||
.merge(defaultOptions[chain] ?: UpstreamsConfig.Options.getDefaults())
|
||||
val upstream = when (BlockchainType.from(chain)) {
|
||||
BlockchainType.ETHEREUM -> {
|
||||
BlockchainType.EVM_POW -> {
|
||||
buildEthereumUpstream(up.cast(UpstreamsConfig.EthereumConnection::class.java), chain, options)
|
||||
}
|
||||
BlockchainType.BITCOIN -> {
|
||||
buildBitcoinUpstream(up.cast(UpstreamsConfig.BitcoinConnection::class.java), chain, options)
|
||||
}
|
||||
BlockchainType.ETHEREUM_POS -> {
|
||||
BlockchainType.EVM_POS -> {
|
||||
buildEthereumPosUpstream(up.cast(UpstreamsConfig.EthereumPosConnection::class.java), chain, options)
|
||||
}
|
||||
else -> {
|
||||
|
||||
@@ -62,7 +62,7 @@ open class CurrentMultistreamHolder(
|
||||
val chain = change.chain
|
||||
try {
|
||||
when (BlockchainType.from(chain)) {
|
||||
BlockchainType.ETHEREUM -> {
|
||||
BlockchainType.EVM_POW -> {
|
||||
val up = change.upstream.cast(EthereumUpstream::class.java)
|
||||
val current = chainMapping[chain]
|
||||
val factory = Callable<Multistream> {
|
||||
@@ -70,7 +70,7 @@ open class CurrentMultistreamHolder(
|
||||
}
|
||||
processUpdate(change, up, current, factory)
|
||||
}
|
||||
BlockchainType.ETHEREUM_POS -> {
|
||||
BlockchainType.EVM_POS -> {
|
||||
val up = change.upstream.cast(EthereumPosUpstream::class.java)
|
||||
val current = chainMapping[chain]
|
||||
val factory = Callable<Multistream> {
|
||||
@@ -145,9 +145,9 @@ open class CurrentMultistreamHolder(
|
||||
|
||||
fun setupDefaultMethods(chain: Chain): CallMethods {
|
||||
val created = when (BlockchainType.from(chain)) {
|
||||
BlockchainType.ETHEREUM -> DefaultEthereumMethods(chain)
|
||||
BlockchainType.EVM_POW -> DefaultEthereumMethods(chain)
|
||||
BlockchainType.BITCOIN -> DefaultBitcoinMethods()
|
||||
BlockchainType.ETHEREUM_POS -> DefaultEthereumMethods(chain)
|
||||
BlockchainType.EVM_POS -> DefaultEthereumMethods(chain)
|
||||
else -> throw IllegalStateException("Unsupported chain: $chain")
|
||||
}
|
||||
callTargets[chain] = created
|
||||
|
||||
@@ -125,7 +125,7 @@ class DefaultEthereumMethods(
|
||||
Chain.ETHEREUM_CLASSIC == chain -> {
|
||||
"\"1\""
|
||||
}
|
||||
Chain.MATIC == chain -> {
|
||||
Chain.POLYGON == chain -> {
|
||||
"\"137\""
|
||||
}
|
||||
Chain.TESTNET_MORDEN == chain -> {
|
||||
@@ -151,7 +151,7 @@ class DefaultEthereumMethods(
|
||||
Chain.ETHEREUM == chain -> {
|
||||
"\"0x1\""
|
||||
}
|
||||
Chain.MATIC == chain -> {
|
||||
Chain.POLYGON == chain -> {
|
||||
"\"0x89\""
|
||||
}
|
||||
Chain.TESTNET_ROPSTEN == chain -> {
|
||||
|
||||
@@ -111,7 +111,7 @@ class EthereumBlockValidator : BlockValidator {
|
||||
)
|
||||
}
|
||||
|
||||
val timestampValid = it.timestamp > cur.timestamp
|
||||
val timestampValid = it.timestamp >= cur.timestamp
|
||||
if (!timestampValid) {
|
||||
log.warn(
|
||||
"Block timestamp {} not valid for {}. Must be greater than {}",
|
||||
|
||||
@@ -240,6 +240,7 @@ open class WsConnection(
|
||||
.aggregateFrames(msgSizeLimit)
|
||||
.receiveFrames()
|
||||
.map { ByteBufInputStream(it.content()).readAllBytes() }
|
||||
.filter{ it.isNotEmpty() }
|
||||
.flatMap {
|
||||
try {
|
||||
val msg = parser.parse(it)
|
||||
|
||||
@@ -190,11 +190,11 @@ class GrpcUpstreams(
|
||||
)
|
||||
|
||||
val blockchainType = BlockchainType.from(chain)
|
||||
if (blockchainType == BlockchainType.ETHEREUM) {
|
||||
if (blockchainType == BlockchainType.EVM_POW) {
|
||||
return getOrCreateEthereum(chain, metrics)
|
||||
} else if (blockchainType == BlockchainType.BITCOIN) {
|
||||
return getOrCreateBitcoin(chain, metrics)
|
||||
} else if (blockchainType == BlockchainType.ETHEREUM_POS) {
|
||||
} else if (blockchainType == BlockchainType.EVM_POS) {
|
||||
return getOrCreateEthereumPos(chain, metrics)
|
||||
} else {
|
||||
throw IllegalArgumentException("Unsupported blockchain: $chain")
|
||||
|
||||
@@ -27,11 +27,9 @@ import io.emeraldpay.dshackle.upstream.calls.CallMethods
|
||||
import io.emeraldpay.dshackle.upstream.calls.DefaultEthereumMethods
|
||||
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.EthereumPosMultiStream
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.EthereumPosRpcUpstream
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.EthereumReader
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.EthereumRpcUpstream
|
||||
import io.emeraldpay.grpc.BlockchainType
|
||||
import io.emeraldpay.grpc.Chain
|
||||
import org.jetbrains.annotations.NotNull
|
||||
@@ -48,7 +46,7 @@ class MultistreamHolderMock implements MultistreamHolder {
|
||||
|
||||
Multistream addUpstream(@NotNull Chain chain, @NotNull Upstream up) {
|
||||
if (!upstreams.containsKey(chain)) {
|
||||
if (BlockchainType.from(chain) == BlockchainType.ETHEREUM_POS) {
|
||||
if (BlockchainType.from(chain) == BlockchainType.EVM_POS) {
|
||||
if (up instanceof EthereumPosMultiStream) {
|
||||
upstreams[chain] = up
|
||||
} else if (up instanceof EthereumPosRpcUpstream) {
|
||||
|
||||
Reference in New Issue
Block a user