Fix distance for fork and add parentHash to blockContainer (#186)
* Fix distance for fork
This commit is contained in:
@@ -66,6 +66,7 @@ class BlocksRedisCache(
|
||||
false,
|
||||
value.value.toByteArray(),
|
||||
null,
|
||||
BlockId.from(meta.parentHash.toByteArray()),
|
||||
meta.txHashesList.map {
|
||||
TxId(it.toByteArray())
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ abstract class OnBlockRedisCache<T>(
|
||||
.setHash(ByteString.copyFrom(block.hash.value))
|
||||
.setHeight(block.height)
|
||||
.setDifficulty(ByteString.copyFrom(block.difficulty.toByteArray()))
|
||||
.setParentHash(ByteString.copyFrom(block.parentHash?.value ?: byteArrayOf()))
|
||||
.setTimestamp(block.timestamp.toEpochMilli())
|
||||
}
|
||||
|
||||
|
||||
@@ -35,9 +35,10 @@ class BlockContainer(
|
||||
val full: Boolean,
|
||||
json: ByteArray?,
|
||||
val parsed: Any?,
|
||||
val parentHash: BlockId?,
|
||||
val transactions: List<TxId> = emptyList(),
|
||||
val nodeRating: Int = 0,
|
||||
val upstreamId: String = ""
|
||||
val upstreamId: String = "",
|
||||
) : SourceContainer(json, parsed) {
|
||||
val enriched: Boolean = transactions.isNotEmpty()
|
||||
|
||||
@@ -45,6 +46,7 @@ class BlockContainer(
|
||||
@JvmStatic
|
||||
fun from(block: BlockJson<*>, raw: ByteArray, upstreamId: String): BlockContainer {
|
||||
val hasTransactions = !block.transactions?.filterIsInstance<TransactionJson>().isNullOrEmpty()
|
||||
val parent = if (block.parentHash == null) null else BlockId.from(block.parentHash)
|
||||
return BlockContainer(
|
||||
height = block.number,
|
||||
hash = BlockId.from(block),
|
||||
@@ -54,7 +56,8 @@ class BlockContainer(
|
||||
json = raw,
|
||||
parsed = block,
|
||||
transactions = block.transactions?.map { TxId.from(it.hash) } ?: emptyList(),
|
||||
upstreamId = upstreamId
|
||||
upstreamId = upstreamId,
|
||||
parentHash = parent
|
||||
)
|
||||
}
|
||||
|
||||
@@ -91,12 +94,17 @@ class BlockContainer(
|
||||
if (timestamp != other.timestamp) return false
|
||||
if (full != other.full) return false
|
||||
if (transactions != other.transactions) return false
|
||||
if (parentHash != null && other.parentHash != null) {
|
||||
if (parentHash != other.parentHash) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fun copyWithRating(nodeRating: Int): BlockContainer {
|
||||
return BlockContainer(height, hash, difficulty, timestamp, full, json, parsed, transactions, nodeRating)
|
||||
return BlockContainer(
|
||||
height, hash, difficulty, timestamp, full, json, parsed, parentHash, transactions, nodeRating
|
||||
)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
@@ -115,7 +123,6 @@ class BlockContainer(
|
||||
BlockJson<TransactionRefJson>().also {
|
||||
it.number = height
|
||||
it.hash = BlockHash.from(hash.value)
|
||||
it.parentHash = BlockHash.empty()
|
||||
it.timestamp = timestamp
|
||||
it.difficulty = difficulty
|
||||
it.gasLimit = 0
|
||||
@@ -123,6 +130,7 @@ class BlockContainer(
|
||||
it.logsBloom = Bloom.empty()
|
||||
it.miner = Address.empty()
|
||||
it.baseFeePerGas = Wei.ZERO
|
||||
it.parentHash = if (parentHash != null) BlockHash.from(parentHash.value) else BlockHash.empty()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ class StreamHead(
|
||||
.setTimestamp(block.timestamp.toEpochMilli())
|
||||
.setWeight(ByteString.copyFrom(block.difficulty.toByteArray()))
|
||||
.setBlockId(block.hash.toHex())
|
||||
.setParentBlockId(block.parentHash?.toHex() ?: "")
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,10 @@ class DistanceExtractor {
|
||||
|
||||
fun extractPriorityDistance(top: BlockContainer, curr: BlockContainer): ChainDistance {
|
||||
return when {
|
||||
curr.height > top.height -> ChainDistance.Fork
|
||||
(curr.parentHash != null && curr.height - top.height == 1L) ->
|
||||
if (curr.parentHash == top.hash) ChainDistance.Distance(0) else ChainDistance.Fork
|
||||
curr.height == top.height -> if (curr.hash == top.hash) ChainDistance.Distance(0) else ChainDistance.Fork
|
||||
else -> ChainDistance.Distance(top.height - curr.height)
|
||||
else -> ChainDistance.Distance((top.height - curr.height).coerceAtLeast(0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ abstract class HeadLagObserver(
|
||||
.sample(throttling)
|
||||
.flatMap(this::probeFollowers)
|
||||
.map { item ->
|
||||
log.debug("Set to ${item.t2.getId()} lag = ${item.t1}")
|
||||
item.t2.setLag(item.t1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ class ExtractBlock {
|
||||
val data = objectMapper.readValue(json, Map::class.java) as Map<String, Any>
|
||||
|
||||
val hash = data["hash"] as String? ?: throw IllegalArgumentException("Block JSON has no hash")
|
||||
val parentHash = data["previousblockhash"] as String? ?: throw IllegalArgumentException("Block JSON has no previousblockhash")
|
||||
val transactions = (data["tx"] as List<String>?)?.map(TxId.Companion::from) ?: emptyList()
|
||||
|
||||
return BlockContainer(
|
||||
@@ -66,6 +67,7 @@ class ExtractBlock {
|
||||
false,
|
||||
json,
|
||||
data,
|
||||
BlockId.from(parentHash),
|
||||
transactions
|
||||
)
|
||||
}
|
||||
|
||||
@@ -67,6 +67,9 @@ class BitcoinGrpcUpstream(
|
||||
private val extractBlock = ExtractBlock()
|
||||
private val defaultReader: JsonRpcReader = client.getReader()
|
||||
private val blockConverter: Function<BlockchainOuterClass.ChainHead, BlockContainer> = Function { value ->
|
||||
val parentHash =
|
||||
if (value.parentBlockId.isBlank()) null
|
||||
else BlockId.from(value.parentBlockId)
|
||||
val block = BlockContainer(
|
||||
value.height,
|
||||
BlockId.from(value.blockId),
|
||||
@@ -74,7 +77,8 @@ class BitcoinGrpcUpstream(
|
||||
Instant.ofEpochMilli(value.timestamp),
|
||||
false,
|
||||
null,
|
||||
null
|
||||
null,
|
||||
parentHash
|
||||
)
|
||||
block
|
||||
}
|
||||
|
||||
@@ -73,6 +73,9 @@ open class EthereumGrpcUpstream(
|
||||
Lifecycle {
|
||||
|
||||
private val blockConverter: Function<BlockchainOuterClass.ChainHead, BlockContainer> = Function { value ->
|
||||
val parentHash =
|
||||
if (value.parentBlockId.isBlank()) null
|
||||
else BlockId.from(BlockHash.from("0x" + value.parentBlockId))
|
||||
val block = BlockContainer(
|
||||
value.height,
|
||||
BlockId.from(BlockHash.from("0x" + value.blockId)),
|
||||
@@ -80,7 +83,8 @@ open class EthereumGrpcUpstream(
|
||||
Instant.ofEpochMilli(value.timestamp),
|
||||
false,
|
||||
null,
|
||||
null
|
||||
null,
|
||||
parentHash
|
||||
)
|
||||
block
|
||||
}
|
||||
|
||||
@@ -67,6 +67,9 @@ open class EthereumPosGrpcUpstream(
|
||||
Lifecycle {
|
||||
|
||||
private val blockConverter: Function<BlockchainOuterClass.ChainHead, BlockContainer> = Function { value ->
|
||||
val parentHash =
|
||||
if (value.parentBlockId.isBlank()) null
|
||||
else BlockId.from(BlockHash.from("0x" + value.parentBlockId))
|
||||
val block = BlockContainer(
|
||||
value.height,
|
||||
BlockId.from(BlockHash.from("0x" + value.blockId)),
|
||||
@@ -74,7 +77,8 @@ open class EthereumPosGrpcUpstream(
|
||||
Instant.ofEpochMilli(value.timestamp),
|
||||
false,
|
||||
null,
|
||||
null
|
||||
null,
|
||||
parentHash
|
||||
)
|
||||
block
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ message BlockMeta {
|
||||
bytes difficulty = 3;
|
||||
uint64 timestamp = 4;
|
||||
repeated bytes tx_hashes = 5;
|
||||
bytes parent_hash = 6;
|
||||
}
|
||||
|
||||
message TxMeta {
|
||||
|
||||
Reference in New Issue
Block a user