solution: upgrade to api 0.2
This commit is contained in:
@@ -44,7 +44,7 @@ configurations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile "io.emeraldpay:emerald-grpc:0.1-SNAPSHOT"
|
compile "io.emeraldpay:emerald-grpc:0.2"
|
||||||
|
|
||||||
compile "io.grpc:grpc-protobuf:${grpcVersion}"
|
compile "io.grpc:grpc-protobuf:${grpcVersion}"
|
||||||
compile "io.grpc:grpc-stub:${grpcVersion}"
|
compile "io.grpc:grpc-stub:${grpcVersion}"
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import io.emeraldpay.api.proto.Common
|
|||||||
import io.emeraldpay.grpc.Chain
|
import io.emeraldpay.grpc.Chain
|
||||||
import io.grpc.stub.StreamObserver
|
import io.grpc.stub.StreamObserver
|
||||||
import io.infinitape.etherjar.domain.TransactionId
|
import io.infinitape.etherjar.domain.TransactionId
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@@ -18,7 +19,9 @@ class BlockchainRpc(
|
|||||||
@Autowired private val trackAddress: TrackAddress
|
@Autowired private val trackAddress: TrackAddress
|
||||||
): BlockchainGrpc.BlockchainImplBase() {
|
): BlockchainGrpc.BlockchainImplBase() {
|
||||||
|
|
||||||
override fun nativeCall(request: BlockchainOuterClass.CallBlockchainRequest, responseObserver: StreamObserver<BlockchainOuterClass.CallBlockchainReplyItem>) {
|
private val log = LoggerFactory.getLogger(BlockchainRpc::class.java)
|
||||||
|
|
||||||
|
override fun nativeCall(request: BlockchainOuterClass.NativeCallRequest, responseObserver: StreamObserver<BlockchainOuterClass.NativeCallReplyItem>) {
|
||||||
nativeCall.nativeCall(request, responseObserver)
|
nativeCall.nativeCall(request, responseObserver)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,18 +29,31 @@ class BlockchainRpc(
|
|||||||
streamHead.add(Chain.byId(request.type.number), responseObserver)
|
streamHead.add(Chain.byId(request.type.number), responseObserver)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun trackTx(request: BlockchainOuterClass.TrackTxRequest, responseObserver: StreamObserver<BlockchainOuterClass.TxStatus>) {
|
override fun streamTxStatus(request: BlockchainOuterClass.TxStatusRequest, responseObserver: StreamObserver<BlockchainOuterClass.TxStatus>) {
|
||||||
val tx = TrackTx.TrackedTx(
|
val tx = TrackTx.TrackedTx(
|
||||||
Chain.byId(request.chainValue),
|
Chain.byId(request.chainValue),
|
||||||
StreamSender(responseObserver),
|
StreamSender(responseObserver),
|
||||||
Instant.now(),
|
Instant.now(),
|
||||||
TransactionId.from(request.txid),
|
TransactionId.from(request.txId),
|
||||||
Math.min(Math.max(1, request.confirmations), 100)
|
Math.min(Math.max(1, request.confirmationLimit), 100)
|
||||||
)
|
)
|
||||||
trackTx.add(tx)
|
trackTx.add(tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun trackAddress(request: BlockchainOuterClass.TrackAddressRequest, responseObserver: StreamObserver<BlockchainOuterClass.AddressStatus>) {
|
override fun streamBalance(request: BlockchainOuterClass.BalanceRequest, responseObserver: StreamObserver<BlockchainOuterClass.AddressBalance>) {
|
||||||
trackAddress.add(request, responseObserver)
|
trackAddress.add(request, responseObserver)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getBalance(request: BlockchainOuterClass.BalanceRequest, responseObserver: StreamObserver<BlockchainOuterClass.AddressBalance>) {
|
||||||
|
val addresses = trackAddress.initializeFor(request, responseObserver)
|
||||||
|
trackAddress.send(request, addresses)
|
||||||
|
.doOnError { t ->
|
||||||
|
log.error("Failed to process balance", t)
|
||||||
|
responseObserver.onError(Exception("Internal error"))
|
||||||
|
}
|
||||||
|
.subscribe {
|
||||||
|
responseObserver.onCompleted()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,6 @@ import io.emeraldpay.api.proto.BlockchainOuterClass
|
|||||||
import io.emeraldpay.dshackle.upstream.Upstreams
|
import io.emeraldpay.dshackle.upstream.Upstreams
|
||||||
import io.emeraldpay.grpc.Chain
|
import io.emeraldpay.grpc.Chain
|
||||||
import io.grpc.stub.StreamObserver
|
import io.grpc.stub.StreamObserver
|
||||||
import io.infinitape.etherjar.rpc.json.ResponseJson
|
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
@@ -23,9 +22,7 @@ class NativeCall(
|
|||||||
|
|
||||||
private val log = LoggerFactory.getLogger(NativeCall::class.java)
|
private val log = LoggerFactory.getLogger(NativeCall::class.java)
|
||||||
|
|
||||||
|
open fun nativeCall(request: BlockchainOuterClass.NativeCallRequest, responseObserver: StreamObserver<BlockchainOuterClass.NativeCallReplyItem>) {
|
||||||
|
|
||||||
open fun nativeCall(request: BlockchainOuterClass.CallBlockchainRequest, responseObserver: StreamObserver<BlockchainOuterClass.CallBlockchainReplyItem>) {
|
|
||||||
val chain= Chain.byId(request.chain.number)
|
val chain= Chain.byId(request.chain.number)
|
||||||
if (chain == Chain.UNSPECIFIED) {
|
if (chain == Chain.UNSPECIFIED) {
|
||||||
throw Exception("Invalid chain id: ${request.chain.number}")
|
throw Exception("Invalid chain id: ${request.chain.number}")
|
||||||
@@ -49,7 +46,7 @@ class NativeCall(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.map {
|
.map {
|
||||||
BlockchainOuterClass.CallBlockchainReplyItem.newBuilder()
|
BlockchainOuterClass.NativeCallReplyItem.newBuilder()
|
||||||
.setSucceed(true)
|
.setSucceed(true)
|
||||||
.setId(it.id)
|
.setId(it.id)
|
||||||
.setPayload(ByteString.copyFrom(it.payload))
|
.setPayload(ByteString.copyFrom(it.payload))
|
||||||
@@ -62,7 +59,7 @@ class NativeCall(
|
|||||||
log.error("Lost context for a native call", it)
|
log.error("Lost context for a native call", it)
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
return@onErrorResume BlockchainOuterClass.CallBlockchainReplyItem.newBuilder()
|
return@onErrorResume BlockchainOuterClass.NativeCallReplyItem.newBuilder()
|
||||||
.setSucceed(false)
|
.setSucceed(false)
|
||||||
.setId(id)
|
.setId(id)
|
||||||
.build()
|
.build()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.emeraldpay.dshackle.rpc
|
package io.emeraldpay.dshackle.rpc
|
||||||
|
|
||||||
|
import com.google.protobuf.ByteString
|
||||||
import io.emeraldpay.api.proto.BlockchainOuterClass
|
import io.emeraldpay.api.proto.BlockchainOuterClass
|
||||||
import io.emeraldpay.dshackle.upstream.Upstreams
|
import io.emeraldpay.dshackle.upstream.Upstreams
|
||||||
import io.emeraldpay.grpc.Chain
|
import io.emeraldpay.grpc.Chain
|
||||||
@@ -26,7 +27,7 @@ class StreamHead(
|
|||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
fun init() {
|
fun init() {
|
||||||
listOf(Chain.ETHEREUM, Chain.ETHEREUM_CLASSIC, Chain.MORDEN).forEach { chain ->
|
listOf(Chain.ETHEREUM, Chain.ETHEREUM_CLASSIC, Chain.TESTNET_MORDEN, Chain.TESTNET_KOVAN).forEach { chain ->
|
||||||
if (upstreams.ethereumUpstream(chain)?.head != null) {
|
if (upstreams.ethereumUpstream(chain)?.head != null) {
|
||||||
clients[chain] = ConcurrentLinkedQueue()
|
clients[chain] = ConcurrentLinkedQueue()
|
||||||
subscribe(chain)
|
subscribe(chain)
|
||||||
@@ -77,7 +78,9 @@ class StreamHead(
|
|||||||
val data = BlockchainOuterClass.ChainHead.newBuilder()
|
val data = BlockchainOuterClass.ChainHead.newBuilder()
|
||||||
.setChainValue(chain.id)
|
.setChainValue(chain.id)
|
||||||
.setHeight(block.number)
|
.setHeight(block.number)
|
||||||
.setHash(block.hash.toHex())
|
.setTimestamp(block.timestamp.time)
|
||||||
|
.setWeight(ByteString.copyFrom(block.totalDifficulty.toByteArray()))
|
||||||
|
.setBlockId(block.hash.toHex().substring(2))
|
||||||
.build()
|
.build()
|
||||||
var sent: Boolean = false
|
var sent: Boolean = false
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package io.emeraldpay.dshackle.rpc
|
package io.emeraldpay.dshackle.rpc
|
||||||
|
|
||||||
import com.google.protobuf.ByteString
|
|
||||||
import io.emeraldpay.api.proto.BlockchainOuterClass
|
import io.emeraldpay.api.proto.BlockchainOuterClass
|
||||||
import io.emeraldpay.api.proto.Common
|
import io.emeraldpay.api.proto.Common
|
||||||
import io.emeraldpay.dshackle.upstream.Upstreams
|
import io.emeraldpay.dshackle.upstream.Upstreams
|
||||||
@@ -17,11 +16,13 @@ import org.springframework.stereotype.Service
|
|||||||
import reactor.core.publisher.Flux
|
import reactor.core.publisher.Flux
|
||||||
import reactor.core.publisher.Mono
|
import reactor.core.publisher.Mono
|
||||||
import reactor.core.publisher.toFlux
|
import reactor.core.publisher.toFlux
|
||||||
|
import reactor.math.sum
|
||||||
import reactor.util.function.Tuple2
|
import reactor.util.function.Tuple2
|
||||||
import reactor.util.function.Tuples
|
import reactor.util.function.Tuples
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
import java.util.*
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue
|
import java.util.concurrent.ConcurrentLinkedQueue
|
||||||
import java.util.concurrent.Future
|
import java.util.concurrent.Future
|
||||||
import javax.annotation.PostConstruct
|
import javax.annotation.PostConstruct
|
||||||
@@ -33,7 +34,7 @@ class TrackAddress(
|
|||||||
|
|
||||||
private val clients = HashMap<Chain, ConcurrentLinkedQueue<TrackedAddress>>()
|
private val clients = HashMap<Chain, ConcurrentLinkedQueue<TrackedAddress>>()
|
||||||
|
|
||||||
private val allChains = listOf(Chain.MORDEN, Chain.ETHEREUM_CLASSIC, Chain.ETHEREUM)
|
private val allChains = listOf(Chain.TESTNET_MORDEN, Chain.ETHEREUM_CLASSIC, Chain.ETHEREUM, Chain.TESTNET_KOVAN)
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
fun init() {
|
fun init() {
|
||||||
@@ -59,18 +60,18 @@ class TrackAddress(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun add(request: BlockchainOuterClass.TrackAddressRequest, responseObserver: StreamObserver<BlockchainOuterClass.AddressStatus>) {
|
fun initializeFor(request: BlockchainOuterClass.BalanceRequest, responseObserver: StreamObserver<BlockchainOuterClass.AddressBalance>): List<TrackedAddress> {
|
||||||
val chain = Chain.byId(request.asset.chainValue)
|
val chain = Chain.byId(request.asset.chainValue)
|
||||||
if (!allChains.contains(chain)) {
|
if (!allChains.contains(chain)) {
|
||||||
responseObserver.onError(Exception("Unsupported chain ${request.asset.chainValue}"))
|
responseObserver.onError(Exception("Unsupported chain ${request.asset.chainValue}"))
|
||||||
return
|
return Collections.emptyList()
|
||||||
}
|
}
|
||||||
if (request.asset.code?.toLowerCase() != "ether") {
|
if (request.asset.code?.toLowerCase() != "ether") {
|
||||||
responseObserver.onError(Exception("Unsupported asset ${request.asset.code}"))
|
responseObserver.onError(Exception("Unsupported asset ${request.asset.code}"))
|
||||||
return
|
return Collections.emptyList()
|
||||||
}
|
}
|
||||||
val new = java.util.ArrayList<TrackedAddress>()
|
val new = java.util.ArrayList<TrackedAddress>()
|
||||||
val observer = StreamSender<BlockchainOuterClass.AddressStatus>(responseObserver)
|
val observer = StreamSender<BlockchainOuterClass.AddressBalance>(responseObserver)
|
||||||
if (request.address.addrTypeCase == Common.AnyAddress.AddrTypeCase.ADDRESS_SINGLE) {
|
if (request.address.addrTypeCase == Common.AnyAddress.AddrTypeCase.ADDRESS_SINGLE) {
|
||||||
new.add(forAddress(request.address.addressSingle, chain, observer))
|
new.add(forAddress(request.address.addressSingle, chain, observer))
|
||||||
} else if (request.address.addrTypeCase == Common.AnyAddress.AddrTypeCase.ADDRESS_MULTI) {
|
} else if (request.address.addrTypeCase == Common.AnyAddress.AddrTypeCase.ADDRESS_MULTI) {
|
||||||
@@ -78,11 +79,27 @@ class TrackAddress(
|
|||||||
new.add(forAddress(address, chain, observer))
|
new.add(forAddress(address, chain, observer))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
verify(chain, new).subscribe()
|
return new
|
||||||
clients[chain]?.addAll(new)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun forAddress(address: Common.SingleAddress, chain: Chain, observer: StreamSender<BlockchainOuterClass.AddressStatus>): TrackedAddress {
|
fun send(request: BlockchainOuterClass.BalanceRequest, addresses: List<TrackedAddress>): Mono<Long> {
|
||||||
|
val chain = Chain.byId(request.asset.chainValue)
|
||||||
|
return verify(chain, addresses)
|
||||||
|
.map { updated -> notify(updated); 1 }
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun add(request: BlockchainOuterClass.BalanceRequest, responseObserver: StreamObserver<BlockchainOuterClass.AddressBalance>) {
|
||||||
|
val chain = Chain.byId(request.asset.chainValue)
|
||||||
|
val new = initializeFor(request, responseObserver)
|
||||||
|
send(request, new)
|
||||||
|
.doFinally {
|
||||||
|
clients[chain]?.addAll(new)
|
||||||
|
}
|
||||||
|
.subscribe()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun forAddress(address: Common.SingleAddress, chain: Chain, observer: StreamSender<BlockchainOuterClass.AddressBalance>): TrackedAddress {
|
||||||
val addressParsed = Address.from(address.address)
|
val addressParsed = Address.from(address.address)
|
||||||
return TrackedAddress(
|
return TrackedAddress(
|
||||||
chain,
|
chain,
|
||||||
@@ -130,8 +147,8 @@ class TrackAddress(
|
|||||||
|
|
||||||
private fun notify(address: TrackedAddress): Boolean {
|
private fun notify(address: TrackedAddress): Boolean {
|
||||||
val sent = address.stream.send(
|
val sent = address.stream.send(
|
||||||
BlockchainOuterClass.AddressStatus.newBuilder()
|
BlockchainOuterClass.AddressBalance.newBuilder()
|
||||||
.setBalance(ByteString.copyFrom(address.balance!!.amount!!.toByteArray()))
|
.setBalance(address.balance!!.amount!!.toString(10))
|
||||||
.setAsset(Common.Asset.newBuilder()
|
.setAsset(Common.Asset.newBuilder()
|
||||||
.setChainValue(address.chain.id)
|
.setChainValue(address.chain.id)
|
||||||
.setCode("ETHER")
|
.setCode("ETHER")
|
||||||
@@ -149,7 +166,7 @@ class TrackAddress(
|
|||||||
class Update(val addr: TrackedAddress, val value: Future<Wei>)
|
class Update(val addr: TrackedAddress, val value: Future<Wei>)
|
||||||
|
|
||||||
class TrackedAddress(val chain: Chain,
|
class TrackedAddress(val chain: Chain,
|
||||||
val stream: StreamSender<BlockchainOuterClass.AddressStatus>,
|
val stream: StreamSender<BlockchainOuterClass.AddressBalance>,
|
||||||
val address: Address,
|
val address: Address,
|
||||||
val since: Instant = Instant.now(),
|
val since: Instant = Instant.now(),
|
||||||
var lastPing: Instant = Instant.now(),
|
var lastPing: Instant = Instant.now(),
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import reactor.core.publisher.Mono
|
|||||||
import reactor.core.publisher.toFlux
|
import reactor.core.publisher.toFlux
|
||||||
import reactor.kotlin.core.publisher.switchIfEmpty
|
import reactor.kotlin.core.publisher.switchIfEmpty
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
|
import java.math.BigInteger
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue
|
import java.util.concurrent.ConcurrentLinkedQueue
|
||||||
@@ -34,7 +35,7 @@ class TrackTx(
|
|||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
fun init() {
|
fun init() {
|
||||||
listOf(Chain.MORDEN, Chain.ETHEREUM_CLASSIC, Chain.ETHEREUM).forEach { chain ->
|
listOf(Chain.TESTNET_MORDEN, Chain.ETHEREUM_CLASSIC, Chain.ETHEREUM, Chain.TESTNET_KOVAN).forEach { chain ->
|
||||||
clients[chain] = ConcurrentLinkedQueue()
|
clients[chain] = ConcurrentLinkedQueue()
|
||||||
upstreams.ethereumUpstream(chain)?.head?.let { head ->
|
upstreams.ethereumUpstream(chain)?.head?.let { head ->
|
||||||
head.getFlux().subscribe { verifyAll(chain) }
|
head.getFlux().subscribe { verifyAll(chain) }
|
||||||
@@ -61,6 +62,27 @@ class TrackTx(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun loadWeight(tx: TrackedTx): Mono<TrackedTx> {
|
||||||
|
val batch = Batch()
|
||||||
|
val execution = Mono
|
||||||
|
.fromCompletionStage(batch.add(Commands.eth().getBlock(tx.status.blockHash)))
|
||||||
|
.map { block ->
|
||||||
|
if (block != null && block.number != null && block.totalDifficulty != null) {
|
||||||
|
tx.withStatus(
|
||||||
|
blockTotalDifficulty = block.totalDifficulty,
|
||||||
|
blockTime = block.timestamp.toInstant()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
tx.withStatus(
|
||||||
|
mined = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val upstream = upstreams.ethereumUpstream(tx.chain)!!
|
||||||
|
upstream.api.execute(batch)
|
||||||
|
return execution
|
||||||
|
}
|
||||||
|
|
||||||
private fun verify(tx: TrackedTx): Boolean {
|
private fun verify(tx: TrackedTx): Boolean {
|
||||||
val found = tx.status.found
|
val found = tx.status.found
|
||||||
val mined = tx.status.mined
|
val mined = tx.status.mined
|
||||||
@@ -80,10 +102,9 @@ class TrackTx(
|
|||||||
)
|
)
|
||||||
return@flatMap upstream.head.getHead().map { head ->
|
return@flatMap upstream.head.getHead().map { head ->
|
||||||
tx.withStatus(
|
tx.withStatus(
|
||||||
confirmation = head.number - tx.status.height!! + 1,
|
confirmation = head.number - tx.status.height!! + 1
|
||||||
blockTime = head.timestamp.toInstant()
|
|
||||||
)
|
)
|
||||||
}
|
}.flatMap(this::loadWeight)
|
||||||
} else {
|
} else {
|
||||||
tx.withStatus(
|
tx.withStatus(
|
||||||
found = true,
|
found = true,
|
||||||
@@ -110,8 +131,7 @@ class TrackTx(
|
|||||||
private fun notify(tx: TrackedTx): Boolean {
|
private fun notify(tx: TrackedTx): Boolean {
|
||||||
val client = tx.stream
|
val client = tx.stream
|
||||||
val data = BlockchainOuterClass.TxStatus.newBuilder()
|
val data = BlockchainOuterClass.TxStatus.newBuilder()
|
||||||
.setChainValue(tx.chain.id)
|
.setTxId(tx.txid.toHex())
|
||||||
.setTxid(tx.txid.toHex())
|
|
||||||
.setConfirmations(tx.status.confirmation.toInt())
|
.setConfirmations(tx.status.confirmation.toInt())
|
||||||
.setMined(tx.status.mined)
|
.setMined(tx.status.mined)
|
||||||
.setBroadcasted(tx.status.found)
|
.setBroadcasted(tx.status.found)
|
||||||
@@ -119,7 +139,9 @@ class TrackTx(
|
|||||||
if (tx.status.mined) {
|
if (tx.status.mined) {
|
||||||
data.setBlock(
|
data.setBlock(
|
||||||
Common.BlockInfo.newBuilder()
|
Common.BlockInfo.newBuilder()
|
||||||
.setHash(ByteString.copyFrom(tx.status.blockHash!!.bytes))
|
.setBlockId(tx.status.blockHash!!.toHex().substring(2))
|
||||||
|
.setTimestamp(tx.status.blockTime!!.toEpochMilli())
|
||||||
|
.setWeight(ByteString.copyFrom(tx.status.blockTotalDifficulty!!.toByteArray()))
|
||||||
.setHeight(tx.status.height!!)
|
.setHeight(tx.status.height!!)
|
||||||
.setTimestamp(tx.status.blockTime!!.toEpochMilli())
|
.setTimestamp(tx.status.blockTime!!.toEpochMilli())
|
||||||
)
|
)
|
||||||
@@ -151,8 +173,9 @@ class TrackTx(
|
|||||||
mined: Boolean = this.status.mined,
|
mined: Boolean = this.status.mined,
|
||||||
blockHash: BlockHash? = this.status.blockHash,
|
blockHash: BlockHash? = this.status.blockHash,
|
||||||
blockTime: Instant? = this.status.blockTime,
|
blockTime: Instant? = this.status.blockTime,
|
||||||
|
blockTotalDifficulty: BigInteger? = this.status.blockTotalDifficulty,
|
||||||
confirmation: Long = this.status.confirmation): TrackedTx {
|
confirmation: Long = this.status.confirmation): TrackedTx {
|
||||||
this.status = this.status.copy(found, height, mined, blockHash, blockTime, confirmation)
|
this.status = this.status.copy(found, height, mined, blockHash, blockTime, blockTotalDifficulty, confirmation)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,14 +190,16 @@ class TrackTx(
|
|||||||
var mined: Boolean = false,
|
var mined: Boolean = false,
|
||||||
var blockHash: BlockHash? = null,
|
var blockHash: BlockHash? = null,
|
||||||
var blockTime: Instant? = null,
|
var blockTime: Instant? = null,
|
||||||
|
var blockTotalDifficulty: BigInteger? = null,
|
||||||
var confirmation: Long = 0) {
|
var confirmation: Long = 0) {
|
||||||
fun copy(found: Boolean = this.found,
|
fun copy(found: Boolean = this.found,
|
||||||
height: Long? = this.height,
|
height: Long? = this.height,
|
||||||
mined: Boolean = this.mined,
|
mined: Boolean = this.mined,
|
||||||
blockHash: BlockHash? = this.blockHash,
|
blockHash: BlockHash? = this.blockHash,
|
||||||
blockTime: Instant? = this.blockTime,
|
blockTime: Instant? = this.blockTime,
|
||||||
|
blockTotalDifficulty: BigInteger? = this.blockTotalDifficulty,
|
||||||
confirmation: Long = this.confirmation)
|
confirmation: Long = this.confirmation)
|
||||||
= TxStatus(found, height, mined, blockHash, blockTime, confirmation)
|
= TxStatus(found, height, mined, blockHash, blockTime, blockTotalDifficulty, confirmation)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -123,9 +123,12 @@ class EthereumApi(
|
|||||||
if (Chain.ETHEREUM_CLASSIC == chain) {
|
if (Chain.ETHEREUM_CLASSIC == chain) {
|
||||||
return "1"
|
return "1"
|
||||||
}
|
}
|
||||||
if (Chain.MORDEN == chain) {
|
if (Chain.TESTNET_MORDEN == chain) {
|
||||||
return "2"
|
return "2"
|
||||||
}
|
}
|
||||||
|
if (Chain.TESTNET_KOVAN == chain) {
|
||||||
|
return "42"
|
||||||
|
}
|
||||||
throw RpcException(-32602, "Invalid chain")
|
throw RpcException(-32602, "Invalid chain")
|
||||||
}
|
}
|
||||||
if ("net_peerCount" == method) {
|
if ("net_peerCount" == method) {
|
||||||
@@ -135,7 +138,7 @@ class EthereumApi(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if ("web3_clientVersion" == method) {
|
if ("web3_clientVersion" == method) {
|
||||||
return "EmeraldDshackle/v0.1"
|
return "EmeraldDshackle/v0.2"
|
||||||
}
|
}
|
||||||
if ("eth_protocolVersion" == method) {
|
if ("eth_protocolVersion" == method) {
|
||||||
return "0x3f"
|
return "0x3f"
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ class Upstreams(
|
|||||||
"ethereum-classic" to Chain.ETHEREUM_CLASSIC,
|
"ethereum-classic" to Chain.ETHEREUM_CLASSIC,
|
||||||
"eth" to Chain.ETHEREUM,
|
"eth" to Chain.ETHEREUM,
|
||||||
"etc" to Chain.ETHEREUM_CLASSIC,
|
"etc" to Chain.ETHEREUM_CLASSIC,
|
||||||
"morden" to Chain.MORDEN
|
"morden" to Chain.TESTNET_MORDEN,
|
||||||
|
"kovan" to Chain.TESTNET_KOVAN
|
||||||
)
|
)
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
|
|||||||
Reference in New Issue
Block a user