Fix distance for fork and add parentHash to blockContainer (#186)

* Fix distance for fork
This commit is contained in:
KirillPamPam
2023-03-28 15:16:39 +04:00
committed by GitHub
parent eac5a4ccf8
commit bdcb7386cd
37 changed files with 163 additions and 30 deletions

View File

@@ -66,6 +66,7 @@ class BlocksRedisCache(
false,
value.value.toByteArray(),
null,
BlockId.from(meta.parentHash.toByteArray()),
meta.txHashesList.map {
TxId(it.toByteArray())
}

View File

@@ -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())
}

View File

@@ -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()
}
}
}

View File

@@ -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()
}
}

View File

@@ -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))
}
}
}

View File

@@ -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)
}
}

View File

@@ -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
)
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -31,6 +31,7 @@ message BlockMeta {
bytes difficulty = 3;
uint64 timestamp = 4;
repeated bytes tx_hashes = 5;
bytes parent_hash = 6;
}
message TxMeta {