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 {
|
||||
|
||||
@@ -49,6 +49,7 @@ class BlockByHeightSpec extends Specification {
|
||||
block.timestamp = Instant.now().truncatedTo(ChronoUnit.SECONDS)
|
||||
block.uncles = []
|
||||
block.transactions = List.of(tx)
|
||||
block.parentHash = BlockHash.from(hash1)
|
||||
|
||||
BlockContainer.from(block).with {
|
||||
blocks.add(it)
|
||||
@@ -77,6 +78,7 @@ class BlockByHeightSpec extends Specification {
|
||||
block1.timestamp = Instant.now().truncatedTo(ChronoUnit.SECONDS)
|
||||
block1.uncles = []
|
||||
block1.transactions = List.of(tx)
|
||||
block1.parentHash = BlockHash.from(hash1)
|
||||
|
||||
def block2 = new BlockJson<TransactionRefJson>()
|
||||
block2.number = 101
|
||||
@@ -85,7 +87,7 @@ class BlockByHeightSpec extends Specification {
|
||||
block2.timestamp = Instant.now().truncatedTo(ChronoUnit.SECONDS)
|
||||
block2.uncles = []
|
||||
block2.transactions = List.of(tx)
|
||||
|
||||
block2.parentHash = BlockHash.from(hash2)
|
||||
|
||||
BlockContainer.from(block1).with {
|
||||
blocks.add(it)
|
||||
@@ -123,6 +125,7 @@ class BlockByHeightSpec extends Specification {
|
||||
block1.timestamp = Instant.now().truncatedTo(ChronoUnit.SECONDS)
|
||||
block1.uncles = []
|
||||
block1.transactions = List.of(tx)
|
||||
block1.parentHash = BlockHash.from(hash1)
|
||||
|
||||
def block2 = new BlockJson<TransactionRefJson>()
|
||||
block2.number = 100
|
||||
@@ -131,6 +134,7 @@ class BlockByHeightSpec extends Specification {
|
||||
block2.timestamp = Instant.now().truncatedTo(ChronoUnit.SECONDS)
|
||||
block2.uncles = []
|
||||
block2.transactions = List.of(tx)
|
||||
block2.parentHash = BlockHash.from(hash2)
|
||||
|
||||
BlockContainer.from(block1).with {
|
||||
blocks.add(it)
|
||||
@@ -159,6 +163,7 @@ class BlockByHeightSpec extends Specification {
|
||||
block.hash = BlockHash.from(hash1)
|
||||
block.totalDifficulty = BigInteger.ONE
|
||||
block.timestamp = Instant.now()
|
||||
block.parentHash = BlockHash.from(hash1)
|
||||
|
||||
// add only to heights
|
||||
BlockContainer.from(block).with {
|
||||
@@ -183,6 +188,7 @@ class BlockByHeightSpec extends Specification {
|
||||
block.hash = BlockHash.from(hash1)
|
||||
block.totalDifficulty = BigInteger.ONE
|
||||
block.timestamp = Instant.now()
|
||||
block.parentHash = BlockHash.from(hash1)
|
||||
|
||||
// add only to blocks
|
||||
BlockContainer.from(block).with {
|
||||
|
||||
@@ -49,6 +49,7 @@ class BlocksMemCacheSpec extends Specification {
|
||||
block.timestamp = Instant.now().truncatedTo(ChronoUnit.SECONDS)
|
||||
block.uncles = []
|
||||
block.transactions = List.of(tx)
|
||||
block.parentHash = BlockHash.from(hash1)
|
||||
|
||||
when:
|
||||
cache.add(BlockContainer.from(block))
|
||||
@@ -73,6 +74,7 @@ class BlocksMemCacheSpec extends Specification {
|
||||
block.timestamp = Instant.now()
|
||||
block.uncles = []
|
||||
block.transactions = List.of(tx)
|
||||
block.parentHash = BlockHash.from(hash1)
|
||||
|
||||
cache.add(BlockContainer.from(block))
|
||||
}
|
||||
@@ -99,6 +101,7 @@ class BlocksMemCacheSpec extends Specification {
|
||||
block.timestamp = Instant.now().truncatedTo(ChronoUnit.SECONDS)
|
||||
block.uncles = []
|
||||
block.transactions = []
|
||||
block.parentHash = BlockHash.from(hash1)
|
||||
|
||||
when:
|
||||
cache.add(BlockContainer.from(block))
|
||||
|
||||
@@ -57,6 +57,7 @@ class CachesSpec extends Specification {
|
||||
block1.totalDifficulty = BigInteger.ONE
|
||||
block1.timestamp = Instant.now()
|
||||
block1.transactions = []
|
||||
block1.parentHash = BlockHash.from(hash1)
|
||||
block1 = BlockContainer.from(block1)
|
||||
|
||||
def block2 = new BlockJson()
|
||||
@@ -65,6 +66,7 @@ class CachesSpec extends Specification {
|
||||
block2.totalDifficulty = BigInteger.ONE
|
||||
block2.timestamp = Instant.now()
|
||||
block2.transactions = []
|
||||
block2.parentHash = BlockHash.from(hash2)
|
||||
block2 = BlockContainer.from(block2)
|
||||
|
||||
when:
|
||||
@@ -98,6 +100,7 @@ class CachesSpec extends Specification {
|
||||
block1.hash = BlockHash.from(hash1)
|
||||
block1.totalDifficulty = BigInteger.ONE
|
||||
block1.timestamp = Instant.now()
|
||||
block1.parentHash = BlockHash.from(hash1)
|
||||
block1 = BlockContainer.from(block1)
|
||||
|
||||
def block2 = new BlockJson()
|
||||
@@ -105,6 +108,7 @@ class CachesSpec extends Specification {
|
||||
block2.hash = BlockHash.from(hash2)
|
||||
block2.totalDifficulty = BigInteger.ONE
|
||||
block2.timestamp = Instant.now()
|
||||
block2.parentHash = BlockHash.from(hash2)
|
||||
block2 = BlockContainer.from(block2)
|
||||
|
||||
when:
|
||||
@@ -138,6 +142,7 @@ class CachesSpec extends Specification {
|
||||
block.hash = BlockHash.from(hash1)
|
||||
block.totalDifficulty = BigInteger.ONE
|
||||
block.timestamp = Instant.now()
|
||||
block.parentHash = BlockHash.from(hash1)
|
||||
block.transactions = [
|
||||
new TransactionRefJson(TransactionId.from(hash1)),
|
||||
new TransactionRefJson(TransactionId.from(hash2)),
|
||||
@@ -170,6 +175,7 @@ class CachesSpec extends Specification {
|
||||
block.totalDifficulty = BigInteger.ONE
|
||||
block.transactions = [tx1, tx2]
|
||||
block.timestamp = Instant.now()
|
||||
block.parentHash = BlockHash.from(hash1)
|
||||
BlockContainer.from(block)
|
||||
}
|
||||
|
||||
@@ -212,6 +218,7 @@ class CachesSpec extends Specification {
|
||||
block.totalDifficulty = BigInteger.ONE
|
||||
block.transactions = [tx1]
|
||||
block.timestamp = Instant.now()
|
||||
block.parentHash = BlockHash.from(hash1)
|
||||
BlockContainer.from(block)
|
||||
}
|
||||
TxMemCache txCache = Mock()
|
||||
|
||||
@@ -27,7 +27,8 @@ class HeightByHashAddingSpec extends Specification {
|
||||
|
||||
def block = new BlockContainer(
|
||||
12079192L, BlockId.from("0xa6af163aab691919c595e2a466f0a7b01f1dff8cfd9631dee811df57064c2d32"),
|
||||
BigInteger.ONE, Instant.now(), false, "".bytes, null, [], 0, "upstream"
|
||||
BigInteger.ONE, Instant.now(), false, "".bytes, null,
|
||||
BlockId.from("0xa6af163aab691919c595e2a466f0a7b01f1dff8cfd9631dee811df57064c2d32"), [], 0, "upstream"
|
||||
)
|
||||
|
||||
def "use memory if available"() {
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package io.emeraldpay.dshackle.cache
|
||||
|
||||
|
||||
import io.emeraldpay.dshackle.data.BlockContainer
|
||||
import io.emeraldpay.etherjar.domain.BlockHash
|
||||
import io.emeraldpay.etherjar.rpc.json.BlockJson
|
||||
@@ -42,6 +41,7 @@ class HeightCacheSpec extends Specification {
|
||||
block.hash = BlockHash.from(hash)
|
||||
block.totalDifficulty = BigInteger.ONE
|
||||
block.timestamp = Instant.now()
|
||||
block.parentHash = BlockHash.from(hash)
|
||||
cache.add(BlockContainer.from(block))
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ class HeightCacheSpec extends Specification {
|
||||
block.hash = BlockHash.from(hash)
|
||||
block.totalDifficulty = BigInteger.ONE
|
||||
block.timestamp = Instant.now()
|
||||
block.parentHash = BlockHash.from(hash)
|
||||
cache.add(BlockContainer.from(block))
|
||||
}
|
||||
cache.purge()
|
||||
|
||||
@@ -86,6 +86,7 @@ class ReceiptMemCacheSpec extends Specification {
|
||||
false,
|
||||
"{}".bytes,
|
||||
null,
|
||||
BlockId.from(receipt.blockHash),
|
||||
[TxId.from(receipt.transactionHash)],
|
||||
0,
|
||||
"unknown"
|
||||
|
||||
@@ -135,6 +135,7 @@ class TxMemCacheSpec extends Specification {
|
||||
|
||||
def block = new BlockJson<TransactionRefJson>()
|
||||
block.hash = BlockHash.from(hash1)
|
||||
block.parentHash = BlockHash.from(hash1)
|
||||
block.number = 100
|
||||
block.totalDifficulty = BigInteger.ONE
|
||||
block.timestamp = Instant.now()
|
||||
|
||||
@@ -62,6 +62,7 @@ class StreamHeadSpec extends Specification {
|
||||
return new BlockJson<TransactionRefJson>().with {
|
||||
it.number = i
|
||||
it.hash = BlockHash.from("0xa0e65cbc1b52a8ca60562112c6060552d882f16f34a9dba2ccdc05c0a6a27${i}")
|
||||
it.parentHash = BlockHash.from("0xa0e65cbc1b52a8ca60562112c6060552d882f16f34a9dba2ccdc05c0a6a27${i}")
|
||||
it.totalDifficulty = i * 1000
|
||||
it.timestamp = Instant.ofEpochMilli(1566000000000 + i * 10000)
|
||||
return it
|
||||
@@ -74,6 +75,7 @@ class StreamHeadSpec extends Specification {
|
||||
.setTimestamp(it.timestamp.toEpochMilli())
|
||||
.setBlockId(it.hash.toHex().substring(2))
|
||||
.setWeight(ByteString.copyFrom(it.totalDifficulty.toByteArray()))
|
||||
.setParentBlockId(it.parentHash.toHex().substring(2))
|
||||
.setHeight(it.number)
|
||||
.build()
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@ class TrackBitcoinAddressSpec extends Specification {
|
||||
Head head = Mock(Head) {
|
||||
1 * getFlux() >> Flux.concat(
|
||||
Flux.just(
|
||||
new BlockContainer(0L, BlockId.from(hash1), BigInteger.ZERO, Instant.now(), false, null, null, [], 0, "TrackBitcoinAddressSpec")
|
||||
new BlockContainer(0L, BlockId.from(hash1), BigInteger.ZERO, Instant.now(), false, null, null, BlockId.from(hash1), [], 0, "TrackBitcoinAddressSpec")
|
||||
),
|
||||
blocks.asFlux()
|
||||
)
|
||||
@@ -309,7 +309,7 @@ class TrackBitcoinAddressSpec extends Specification {
|
||||
StepVerifier.create(resp)
|
||||
.expectNext("0")
|
||||
.then {
|
||||
blocks.tryEmitNext(new BlockContainer(1L, BlockId.from(hash1), BigInteger.ONE, Instant.now(), false, null, null, [], 0, "TrackBitcoinAddressSpec"))
|
||||
blocks.tryEmitNext(new BlockContainer(1L, BlockId.from(hash1), BigInteger.ONE, Instant.now(), false, null, null, BlockId.from(hash1), [], 0, "TrackBitcoinAddressSpec"))
|
||||
}
|
||||
.expectNext("1230000")
|
||||
.then {
|
||||
|
||||
@@ -142,7 +142,8 @@ class TrackBitcoinTxSpec extends Specification {
|
||||
def txid = "69cd44d7c641db82e69824523c7ac0c5c1e5628f025474529cf5ffe64527efc9"
|
||||
// start with the current block
|
||||
def next = Flux.fromIterable([10, 12, 13, 14, 15]).map { h ->
|
||||
new BlockContainer(h.longValue(), BlockId.from("0000000000000000000895d1b9d3898700e1deecc3b0e69f439aa77875e6042f"), BigInteger.ONE, Instant.now(), false, null, null, [], 0, "unknown")
|
||||
def hash = BlockId.from("0000000000000000000895d1b9d3898700e1deecc3b0e69f439aa77875e6042f")
|
||||
new BlockContainer(h.longValue(), hash, BigInteger.ONE, Instant.now(), false, null, null, hash, [], 0, "unknown")
|
||||
}
|
||||
Head head = Mock(Head) {
|
||||
1 * getFlux() >> next
|
||||
@@ -173,7 +174,8 @@ class TrackBitcoinTxSpec extends Specification {
|
||||
def txid = "69cd44d7c641db82e69824523c7ac0c5c1e5628f025474529cf5ffe64527efc9"
|
||||
// start with the current block
|
||||
def next = Flux.fromIterable([10, 12, 13]).map { h ->
|
||||
new BlockContainer(h.longValue(), BlockId.from("0000000000000000000895d1b9d3898700e1deecc3b0e69f439aa77875e6042f"), BigInteger.ONE, Instant.now(), false, null, null, [], 0, "unknown")
|
||||
def hash = BlockId.from("0000000000000000000895d1b9d3898700e1deecc3b0e69f439aa77875e6042f")
|
||||
new BlockContainer(h.longValue(), hash, BigInteger.ONE, Instant.now(), false, null, null, hash, [], 0, "unknown")
|
||||
}
|
||||
Head head = Mock(Head) {
|
||||
1 * getFlux() >> next
|
||||
@@ -268,7 +270,8 @@ class TrackBitcoinTxSpec extends Specification {
|
||||
])
|
||||
}
|
||||
def next = Flux.fromIterable([10, 11, 12]).map { h ->
|
||||
new BlockContainer(h.longValue(), BlockId.from("0000000000000000000895d1b9d3898700e1deecc3b0e69f439aa77875e6042f"), BigInteger.ONE, Instant.now(), false, null, null, [], 0, "unknown")
|
||||
def hash = BlockId.from("0000000000000000000895d1b9d3898700e1deecc3b0e69f439aa77875e6042f")
|
||||
new BlockContainer(h.longValue(), hash, BigInteger.ONE, Instant.now(), false, null, null, hash, [], 0, "unknown")
|
||||
}
|
||||
Head head = Mock(Head) {
|
||||
_ * getFlux() >> next
|
||||
|
||||
@@ -87,10 +87,12 @@ class TrackEthereumAddressSpec extends Specification {
|
||||
.setBalance("65432")
|
||||
.build()
|
||||
|
||||
def hash = BlockHash.from("0xa0e65cbc1b52a8ca60562112c6060552d882f16f34a9dba2ccdc05c0a6a27c22")
|
||||
def block2 = new BlockJson().with {
|
||||
it.number = 1
|
||||
it.totalDifficulty = 100
|
||||
it.hash = BlockHash.from("0xa0e65cbc1b52a8ca60562112c6060552d882f16f34a9dba2ccdc05c0a6a27c22")
|
||||
it.hash = hash
|
||||
it.parentHash = hash
|
||||
it.timestamp = Instant.now().truncatedTo(ChronoUnit.SECONDS)
|
||||
return it
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ class TrackEthereumTxSpec extends Specification {
|
||||
|
||||
def chain = Common.ChainRef.CHAIN_ETHEREUM
|
||||
def txId = "0xba61ce4672751fd6086a9ac2b55547a5555af17535b6c0334ede2ecb6d64070a"
|
||||
|
||||
def parent = BlockHash.from("0xa0e65cbc1b52a8ca60562112c6060552d882f16f34a9dba2ccdc05c0a6a27c22")
|
||||
|
||||
def "Gives details for an old transaction"() {
|
||||
setup:
|
||||
@@ -61,6 +61,7 @@ class TrackEthereumTxSpec extends Specification {
|
||||
it.hash = BlockHash.from("0xa0e65cbc1b52a8ca60562112c6060552d882f16f34a9dba2ccdc05c0a6a27c22")
|
||||
it.timestamp = Instant.ofEpochMilli(156400000000)
|
||||
it.number = 100
|
||||
it.parentHash = parent
|
||||
it.totalDifficulty = BigInteger.valueOf(500)
|
||||
it
|
||||
}
|
||||
@@ -70,6 +71,7 @@ class TrackEthereumTxSpec extends Specification {
|
||||
it.timestamp = Instant.ofEpochMilli(156400200000)
|
||||
it.number = 108
|
||||
it.totalDifficulty = BigInteger.valueOf(800)
|
||||
it.parentHash = parent
|
||||
it.transactions = []
|
||||
it
|
||||
}
|
||||
@@ -198,7 +200,7 @@ class TrackEthereumTxSpec extends Specification {
|
||||
def tx = new TrackEthereumTx.TxDetails(Chain.ETHEREUM, Instant.now(), TransactionId.from(txId), 6)
|
||||
def block = new BlockContainer(
|
||||
100, BlockId.from(txId), BigInteger.ONE, Instant.now(), false, "".bytes, null,
|
||||
[TxId.from(txId)], 0, "unknown"
|
||||
BlockId.from(txId), [TxId.from(txId)], 0, "unknown"
|
||||
)
|
||||
|
||||
when:
|
||||
@@ -219,7 +221,7 @@ class TrackEthereumTxSpec extends Specification {
|
||||
|
||||
def tx = new TrackEthereumTx.TxDetails(Chain.ETHEREUM, Instant.now(), TransactionId.from(txId), 6)
|
||||
def block = new BlockContainer(
|
||||
100, BlockId.from(txId), BigInteger.ONE, Instant.now(), false, "".bytes, null,
|
||||
100, BlockId.from(txId), BigInteger.ONE, Instant.now(), false, "".bytes, null, BlockId.from(txId),
|
||||
[TxId.from("0xa0e65cbc1b52a8ca60562112c6060552d882f16f34a9dba2ccdc05c0a6a27c22")],
|
||||
0, "unknown"
|
||||
)
|
||||
@@ -247,6 +249,7 @@ class TrackEthereumTxSpec extends Specification {
|
||||
it.hash = BlockHash.from("0xa0e65cbc1b52a8ca60562112c6060552d882f16f34a9dba2ccdc05c0a6a2000${i}")
|
||||
it.timestamp = Instant.ofEpochMilli(156400000000 + i * 10000)
|
||||
it.setNumber(100L + i.longValue())
|
||||
it.parentHash = parent
|
||||
it.totalDifficulty = BigInteger.valueOf(500 + i)
|
||||
it
|
||||
}
|
||||
|
||||
@@ -123,6 +123,7 @@ class TestingCommons {
|
||||
static BlockContainer blockForEthereum(Long height) {
|
||||
BlockJson block = new BlockJson().tap {
|
||||
setNumber(height)
|
||||
setParentHash(BlockHash.from("0xc4b01774e426325b50f0c709753ec7cf1f1774439d587dfb91f2a4eeb8179cde"))
|
||||
setHash(BlockHash.from("0xc4b01774e426325b50f0c709753ec7cf1f1774439d587dfb91f2a4eeb8179cde"))
|
||||
setTotalDifficulty(BigInteger.ONE)
|
||||
setTimestamp(predictableTimestamp(height, 14))
|
||||
@@ -131,6 +132,7 @@ class TestingCommons {
|
||||
}
|
||||
|
||||
static BlockContainer blockForBitcoin(Long height) {
|
||||
def parent = BlockId.from(StringUtils.leftPad(height.toString(), 64, "0"))
|
||||
return new BlockContainer(
|
||||
height,
|
||||
BlockId.from(StringUtils.leftPad(height.toString(), 64, "0")),
|
||||
@@ -139,6 +141,7 @@ class TestingCommons {
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
parent,
|
||||
[],
|
||||
0,
|
||||
"upstream"
|
||||
|
||||
@@ -31,7 +31,7 @@ class AbstractHeadSpec extends Specification {
|
||||
def blocks = [1L, 2, 3, 4].collect { i ->
|
||||
byte[] hash = new byte[32]
|
||||
hash[0] = i as byte
|
||||
new BlockContainer(i, BlockId.from(hash), BigInteger.valueOf(i), Instant.now(), false, null, null, [], 0, "AbstractHeadSpec")
|
||||
new BlockContainer(i, BlockId.from(hash), BigInteger.valueOf(i), Instant.now(), false, null, null, BlockId.from(hash), [], 0, "AbstractHeadSpec")
|
||||
}
|
||||
|
||||
def "Calls beforeBlock on each block"() {
|
||||
@@ -93,11 +93,12 @@ class AbstractHeadSpec extends Specification {
|
||||
setup:
|
||||
Sinks.Many<BlockContainer> source = Sinks.many().unicast().onBackpressureBuffer()
|
||||
def head = new TestHead()
|
||||
def hash = BlockId.from(blocks[1].hash.value.clone().tap { it[1] = 0xff as byte })
|
||||
def wrongblock = new BlockContainer(
|
||||
blocks[1].height, BlockId.from(blocks[1].hash.value.clone().tap { it[1] = 0xff as byte }),
|
||||
blocks[1].height, hash,
|
||||
blocks[1].difficulty - 1,
|
||||
Instant.now(),
|
||||
false, null, null, [], 0, "AbstractHeadSpec"
|
||||
false, null, null, hash, [], 0, "AbstractHeadSpec"
|
||||
)
|
||||
when:
|
||||
head.follow(source.asFlux())
|
||||
|
||||
@@ -8,6 +8,8 @@ import spock.lang.Specification
|
||||
import java.time.Instant
|
||||
|
||||
class DistanceExtractorSpec extends Specification {
|
||||
BlockHash parent = BlockHash.from("0x50d26e119968e791970d84a7bf5d0ec474d3ec2ef85d5ec8915210ac6bc09ad7")
|
||||
|
||||
def "Correct distance for PoW"() {
|
||||
expect:
|
||||
def top = new BlockJson().with {
|
||||
@@ -15,6 +17,7 @@ class DistanceExtractorSpec extends Specification {
|
||||
it.totalDifficulty = topDiff
|
||||
it.hash = BlockHash.from("0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915123")
|
||||
it.timestamp = Instant.now()
|
||||
it.parentHash = parent
|
||||
return it
|
||||
}
|
||||
def curr = new BlockJson().with {
|
||||
@@ -22,6 +25,7 @@ class DistanceExtractorSpec extends Specification {
|
||||
it.totalDifficulty = currDiff
|
||||
it.hash = BlockHash.from("0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915123")
|
||||
it.timestamp = Instant.now()
|
||||
it.parentHash = parent
|
||||
return it
|
||||
}
|
||||
delta as DistanceExtractor.ChainDistance == DistanceExtractor.@Companion.extractPowDistance(BlockContainer.from(top), BlockContainer.from(curr))
|
||||
@@ -49,6 +53,7 @@ class DistanceExtractorSpec extends Specification {
|
||||
it.totalDifficulty = 0
|
||||
it.hash = BlockHash.from(hashA == 0 ? hash1 : hash2)
|
||||
it.timestamp = Instant.now()
|
||||
it.parentHash = parent
|
||||
return it
|
||||
}
|
||||
def curr = new BlockJson().with {
|
||||
@@ -56,6 +61,7 @@ class DistanceExtractorSpec extends Specification {
|
||||
it.totalDifficulty = 0
|
||||
it.hash = BlockHash.from(hashB == 0 ? hash1 : hash2)
|
||||
it.timestamp = Instant.now()
|
||||
it.parentHash = top.hash
|
||||
return it
|
||||
}
|
||||
delta as DistanceExtractor.ChainDistance == DistanceExtractor.@Companion.extractPriorityDistance(BlockContainer.from(top), BlockContainer.from(curr))
|
||||
@@ -67,8 +73,36 @@ class DistanceExtractorSpec extends Specification {
|
||||
103 | 0 | 100 | 1 || new DistanceExtractor.ChainDistance.Distance(3)
|
||||
150 | 0 | 100 | 1 || new DistanceExtractor.ChainDistance.Distance(50)
|
||||
|
||||
100 | 0 | 101 | 1 || DistanceExtractor.ChainDistance.Fork.INSTANCE
|
||||
100 | 0 | 102 | 1 || DistanceExtractor.ChainDistance.Fork.INSTANCE
|
||||
100 | 0 | 101 | 1 || new DistanceExtractor.ChainDistance.Distance(0)
|
||||
100 | 0 | 102 | 1 || new DistanceExtractor.ChainDistance.Distance(0)
|
||||
100 | 0 | 100 | 1 || DistanceExtractor.ChainDistance.Fork.INSTANCE
|
||||
}
|
||||
|
||||
def "Correct distance if parentHash is null"() {
|
||||
setup:
|
||||
def hash1 = "0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915123"
|
||||
def hash2 = "0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915124"
|
||||
expect:
|
||||
def top = new BlockJson().with {
|
||||
it.number = topHeight
|
||||
it.totalDifficulty = 0
|
||||
it.hash = BlockHash.from(hashA == 0 ? hash1 : hash2)
|
||||
it.timestamp = Instant.now()
|
||||
it.parentHash = parent
|
||||
return it
|
||||
}
|
||||
def curr = new BlockJson().with {
|
||||
it.number = currHeight
|
||||
it.totalDifficulty = 0
|
||||
it.hash = BlockHash.from(hashB == 0 ? hash1 : hash2)
|
||||
it.timestamp = Instant.now()
|
||||
it.parentHash = null
|
||||
return it
|
||||
}
|
||||
delta as DistanceExtractor.ChainDistance == DistanceExtractor.@Companion.extractPriorityDistance(BlockContainer.from(top), BlockContainer.from(curr))
|
||||
where:
|
||||
topHeight | hashA | currHeight | hashB || delta
|
||||
105 | 0 | 100 | 0 || new DistanceExtractor.ChainDistance.Distance(5)
|
||||
100 | 0 | 101 | 1 || new DistanceExtractor.ChainDistance.Distance(0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import java.time.Duration
|
||||
import java.time.Instant
|
||||
|
||||
class HeadLagObserverSpec extends Specification {
|
||||
def parent = BlockHash.from("0xa0e65cbc1b52a8ca60562112c6060552d882f16f34a9dba2ccdc05c0a6a27c22")
|
||||
|
||||
def "Updates lag distance"() {
|
||||
setup:
|
||||
@@ -49,6 +50,7 @@ class HeadLagObserverSpec extends Specification {
|
||||
return BlockContainer.from(
|
||||
new BlockJson().tap {
|
||||
it.number = i
|
||||
it.parentHash = parent
|
||||
it.totalDifficulty = 2000 + i
|
||||
it.hash = BlockHash.from("0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915" + i)
|
||||
it.timestamp = Instant.now()
|
||||
@@ -91,6 +93,7 @@ class HeadLagObserverSpec extends Specification {
|
||||
return BlockContainer.from(
|
||||
new BlockJson().tap {
|
||||
it.number = i
|
||||
it.parentHash = parent
|
||||
it.totalDifficulty = 2000 + i
|
||||
it.hash = BlockHash.from("0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915" + i)
|
||||
it.timestamp = Instant.now()
|
||||
|
||||
@@ -33,6 +33,7 @@ class DefaultEthereumHeadSpec extends Specification {
|
||||
|
||||
DefaultEthereumHead head = new DefaultEthereumHead("upstream", new MostWorkForkChoice(), BlockValidator.ALWAYS_VALID)
|
||||
ObjectMapper objectMapper = Global.objectMapper
|
||||
BlockHash parent = BlockHash.from("0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915210")
|
||||
|
||||
def blocks = (10L..20L).collect { i ->
|
||||
BlockContainer.from(
|
||||
@@ -41,6 +42,7 @@ class DefaultEthereumHeadSpec extends Specification {
|
||||
it.hash = BlockHash.from("0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec89152" + i)
|
||||
it.totalDifficulty = 11 * i
|
||||
it.timestamp = Instant.now()
|
||||
it.parentHash = parent
|
||||
})
|
||||
}
|
||||
|
||||
@@ -95,6 +97,7 @@ class DefaultEthereumHeadSpec extends Specification {
|
||||
it.number = blocks[3].height
|
||||
it.hash = BlockHash.from(blocks[3].hash.value)
|
||||
it.totalDifficulty = blocks[3].difficulty - 1
|
||||
it.parentHash = parent
|
||||
it.timestamp = Instant.now()
|
||||
})
|
||||
head.follow(Flux.just(blocks[0], blocks[3], block3less))
|
||||
@@ -113,6 +116,7 @@ class DefaultEthereumHeadSpec extends Specification {
|
||||
it.number = blocks[3].height
|
||||
it.hash = BlockHash.from(blocks[3].hash.value)
|
||||
it.totalDifficulty = blocks[3].difficulty + 1
|
||||
it.parentHash = parent
|
||||
it.timestamp = Instant.now()
|
||||
})
|
||||
head.follow(Flux.just(blocks[0], blocks[3], block3less))
|
||||
|
||||
@@ -51,6 +51,7 @@ class EthereumBlockValidatorSpec extends Specification {
|
||||
block.timestamp,
|
||||
true, bytes,
|
||||
block,
|
||||
BlockId.from(block.hash.toHex()),
|
||||
Collections.emptyList(),
|
||||
1,
|
||||
"upstream"
|
||||
|
||||
@@ -43,6 +43,7 @@ class EthereumDirectReaderSpec extends Specification {
|
||||
hash = BlockHash.from(hash1)
|
||||
timestamp = Instant.now()
|
||||
totalDifficulty = BigInteger.ONE
|
||||
parentHash = BlockHash.from(hash1)
|
||||
transactions = []
|
||||
}
|
||||
def up = Mock(Multistream) {
|
||||
@@ -108,6 +109,7 @@ class EthereumDirectReaderSpec extends Specification {
|
||||
hash = BlockHash.from(hash1)
|
||||
timestamp = Instant.now()
|
||||
totalDifficulty = BigInteger.ONE
|
||||
parentHash = BlockHash.from(hash1)
|
||||
transactions = []
|
||||
}
|
||||
def up = Mock(Multistream) {
|
||||
@@ -341,6 +343,7 @@ class EthereumDirectReaderSpec extends Specification {
|
||||
setup:
|
||||
def json = new BlockJson().tap {
|
||||
number = 100
|
||||
parentHash = BlockHash.from(hash1)
|
||||
hash = BlockHash.from(hash1)
|
||||
timestamp = Instant.now()
|
||||
totalDifficulty = BigInteger.ONE
|
||||
@@ -386,6 +389,7 @@ class EthereumDirectReaderSpec extends Specification {
|
||||
hash = BlockHash.from(hash1)
|
||||
timestamp = Instant.now()
|
||||
totalDifficulty = BigInteger.ONE
|
||||
parentHash = BlockHash.from(hash1)
|
||||
transactions = []
|
||||
}
|
||||
def up = Mock(Multistream) {
|
||||
|
||||
@@ -35,11 +35,14 @@ import java.time.temporal.ChronoUnit
|
||||
|
||||
class EthereumWsHeadSpec extends Specification {
|
||||
|
||||
BlockHash parent = BlockHash.from("0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200")
|
||||
|
||||
def "Fetch block"() {
|
||||
setup:
|
||||
def block = new BlockJson<TransactionRefJson>()
|
||||
block.number = 100
|
||||
block.hash = BlockHash.from("0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200")
|
||||
block.parentHash = parent
|
||||
block.timestamp = Instant.now().truncatedTo(ChronoUnit.SECONDS)
|
||||
block.transactions = [
|
||||
new TransactionRefJson(TransactionId.from("0x29229361dc5aa1ec66c323dc7a299e2b61a8c8dd2a3522d41255ec10eca25dd8")),
|
||||
@@ -80,8 +83,10 @@ class EthereumWsHeadSpec extends Specification {
|
||||
def block = new BlockJson<TransactionRefJson>()
|
||||
block.timestamp = Instant.now().truncatedTo(ChronoUnit.SECONDS)
|
||||
block.number = 103
|
||||
block.parentHash = parent
|
||||
block.hash = BlockHash.from("0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200")
|
||||
def secondBlock = new BlockJson<TransactionRefJson>()
|
||||
secondBlock.parentHash = parent
|
||||
secondBlock.timestamp = Instant.now().truncatedTo(ChronoUnit.SECONDS)
|
||||
secondBlock.number = 105
|
||||
secondBlock.hash = BlockHash.from("0x29229361dc5aa1ec66c323dc7a299e2b61a8c8dd2a3522d41255ec10eca25dd8")
|
||||
|
||||
@@ -33,6 +33,8 @@ import java.time.Instant
|
||||
|
||||
class ConnectBlockUpdatesSpec extends Specification {
|
||||
|
||||
BlockHash parent = BlockHash.from("0xe5be2159b2b7daf6b126babdcbaa349da668b92d6b8c7db1350fd527fec4885c")
|
||||
|
||||
def "Extracts updates"() {
|
||||
setup:
|
||||
def connectBlockUpdates = new ConnectBlockUpdates(Stub(EthereumMultistream))
|
||||
@@ -41,6 +43,7 @@ class ConnectBlockUpdatesSpec extends Specification {
|
||||
number = 13412871
|
||||
totalDifficulty = BigInteger.ONE
|
||||
timestamp = Instant.now()
|
||||
parentHash = parent
|
||||
transactions = [
|
||||
new TransactionRefJson(TransactionId.from("0x6c88df9d65ccc9351db65676c3581b29483e8dabb71c48ef7671c44b0d5568af")),
|
||||
new TransactionRefJson(TransactionId.from("0x5c241a64e7ce536fdb6b8912091151f18a23dd71cc76a48a4b7d453e339efbe2"))
|
||||
@@ -74,6 +77,7 @@ class ConnectBlockUpdatesSpec extends Specification {
|
||||
number = 13412871
|
||||
totalDifficulty = BigInteger.ONE
|
||||
timestamp = Instant.now()
|
||||
parentHash = parent
|
||||
transactions = [
|
||||
new TransactionRefJson(TransactionId.from("0x6c88df9d65ccc9351db65676c3581b29483e8dabb71c48ef7671c44b0d5568af")),
|
||||
new TransactionRefJson(TransactionId.from("0x5c241a64e7ce536fdb6b8912091151f18a23dd71cc76a48a4b7d453e339efbe2"))
|
||||
@@ -107,6 +111,7 @@ class ConnectBlockUpdatesSpec extends Specification {
|
||||
number = 13412871
|
||||
totalDifficulty = BigInteger.ONE
|
||||
timestamp = Instant.now()
|
||||
parentHash = parent
|
||||
transactions = [
|
||||
new TransactionRefJson(TransactionId.from("0x6c88df9d65ccc9351db65676c3581b29483e8dabb71c48ef7671c44b0d5568af")),
|
||||
new TransactionRefJson(TransactionId.from("0x5c241a64e7ce536fdb6b8912091151f18a23dd71cc76a48a4b7d453e339efbe2"))
|
||||
@@ -117,6 +122,7 @@ class ConnectBlockUpdatesSpec extends Specification {
|
||||
number = 13412871
|
||||
totalDifficulty = BigInteger.ONE
|
||||
timestamp = Instant.now()
|
||||
parentHash = parent
|
||||
transactions = [
|
||||
new TransactionRefJson(TransactionId.from("0x6c88df9d65ccc9351db65676c3581b29483e8dabb71c48ef7671c44b0d5568af")),
|
||||
new TransactionRefJson(TransactionId.from("0x5c241a64e7ce536fdb6b8912091151f18a23dd71cc76a48a4b7d453e339efbe2"))
|
||||
@@ -126,6 +132,7 @@ class ConnectBlockUpdatesSpec extends Specification {
|
||||
hash = BlockHash.from("0xdb1350fd527fec4885ce5be2159b2b7daf6b126babdcbaa349da668b92d6b8c7")
|
||||
number = 13412872
|
||||
totalDifficulty = BigInteger.ONE
|
||||
parentHash = parent
|
||||
timestamp = Instant.now()
|
||||
transactions = [
|
||||
new TransactionRefJson(TransactionId.from("0x9351db65676c3581b29483e8dabb71c48ef7671c44b0d5568af6c88df9d65ccc")),
|
||||
@@ -168,6 +175,7 @@ class ConnectBlockUpdatesSpec extends Specification {
|
||||
number = 13412871
|
||||
totalDifficulty = BigInteger.ONE
|
||||
timestamp = Instant.now()
|
||||
parentHash = parent
|
||||
transactions = [
|
||||
new TransactionRefJson(TransactionId.from("0x6c88df9d65ccc9351db65676c3581b29483e8dabb71c48ef7671c44b0d5568af")),
|
||||
new TransactionRefJson(TransactionId.from("0x5c241a64e7ce536fdb6b8912091151f18a23dd71cc76a48a4b7d453e339efbe2"))
|
||||
@@ -178,6 +186,7 @@ class ConnectBlockUpdatesSpec extends Specification {
|
||||
number = 13412871
|
||||
totalDifficulty = BigInteger.ONE
|
||||
timestamp = Instant.now()
|
||||
parentHash = parent
|
||||
transactions = [
|
||||
new TransactionRefJson(TransactionId.from("0x6c88df9d65ccc9351db65676c3581b29483e8dabb71c48ef7671c44b0d5568af")),
|
||||
new TransactionRefJson(TransactionId.from("0x5c241a64e7ce536fdb6b8912091151f18a23dd71cc76a48a4b7d453e339efbe2"))
|
||||
|
||||
@@ -11,7 +11,7 @@ class MostWorkForkChoiceSpec extends Specification {
|
||||
def blocks = [1L, 2, 3, 4].collect { i ->
|
||||
byte[] hash = new byte[32]
|
||||
hash[0] = i as byte
|
||||
new BlockContainer(i, BlockId.from(hash), BigInteger.valueOf(i), Instant.now(), false, null, null, [], 0, "MostWorkForkChoiceSpec")
|
||||
new BlockContainer(i, BlockId.from(hash), BigInteger.valueOf(i), Instant.now(), false, null, null, BlockId.from(hash), [], 0, "MostWorkForkChoiceSpec")
|
||||
}
|
||||
|
||||
def "filters blocks"() {
|
||||
|
||||
@@ -10,7 +10,7 @@ class NoChoiceWithPriorityForkChoiceSpec extends Specification {
|
||||
def blocks = [1L, 2, 3, 4].collect { i ->
|
||||
byte[] hash = new byte[32]
|
||||
hash[0] = i as byte
|
||||
new BlockContainer(i, BlockId.from(hash), BigInteger.valueOf(i), Instant.now(), false, null, null, [], 0, "NoChoiceWithPriorityForkChoiceSpec")
|
||||
new BlockContainer(i, BlockId.from(hash), BigInteger.valueOf(i), Instant.now(), false, null, null, BlockId.from(hash), [], 0, "NoChoiceWithPriorityForkChoiceSpec")
|
||||
}
|
||||
|
||||
def "filters blocks"() {
|
||||
|
||||
@@ -10,7 +10,7 @@ class PriorityForkChoiceSpec extends Specification {
|
||||
def blocks = [1L, 2, 3, 4].collect { i ->
|
||||
byte[] hash = new byte[32]
|
||||
hash[0] = i as byte
|
||||
new BlockContainer(i, BlockId.from(hash), BigInteger.valueOf(i), Instant.now(), false, null, null, [], i.toInteger(), "PriorityForkChoiceSpec")
|
||||
new BlockContainer(i, BlockId.from(hash), BigInteger.valueOf(i), Instant.now(), false, null, null, BlockId.from(hash), [], i.toInteger(), "PriorityForkChoiceSpec")
|
||||
}
|
||||
def "filters blocks"() {
|
||||
def choice = new PriorityForkChoice()
|
||||
|
||||
@@ -51,6 +51,7 @@ class EthereumGrpcUpstreamSpec extends Specification {
|
||||
Timer.builder("test1").register(TestingCommons.meterRegistry),
|
||||
Counter.builder("test2").register(TestingCommons.meterRegistry)
|
||||
)
|
||||
BlockHash parent = BlockHash.from("0x50d26e119968e791970d84a7bf5d0ec474d3ec2ef85d5ec8915210ac6bc09ad7")
|
||||
|
||||
def hash = (byte)123
|
||||
def buildInfo = new BuildInfo("v0.0.1-test")
|
||||
@@ -65,6 +66,7 @@ class EthereumGrpcUpstreamSpec extends Specification {
|
||||
it.hash = BlockHash.from("0x50d26e119968e791970d84a7bf5d0ec474d3ec2ef85d5ec8915210ac6bc09ad7")
|
||||
it.totalDifficulty = new BigInteger("35bbde5595de6456", 16)
|
||||
it.timestamp = Instant.now()
|
||||
it.parentHash = parent
|
||||
return it
|
||||
}
|
||||
api.answer("eth_getBlockByHash", [block1.hash.toHex(), false], block1)
|
||||
@@ -81,6 +83,7 @@ class EthereumGrpcUpstreamSpec extends Specification {
|
||||
BlockchainOuterClass.ChainHead.newBuilder()
|
||||
.setBlockId(block1.hash.toHex().substring(2))
|
||||
.setHeight(block1.number)
|
||||
.setParentBlockId(parent.toHex().substring(2))
|
||||
.setWeight(ByteString.copyFrom(block1.totalDifficulty.toByteArray()))
|
||||
.build()
|
||||
)
|
||||
@@ -115,6 +118,7 @@ class EthereumGrpcUpstreamSpec extends Specification {
|
||||
it.hash = BlockHash.from("0x50d26e119968e791970d84a7bf5d0ec474d3ec2ef85d5ec8915210ac6bc09ad7")
|
||||
it.totalDifficulty = new BigInteger("35bbde5595de6456", 16)
|
||||
it.timestamp = Instant.now()
|
||||
it.parentHash = parent
|
||||
return it
|
||||
}
|
||||
def block2 = new BlockJson().with {
|
||||
@@ -122,6 +126,7 @@ class EthereumGrpcUpstreamSpec extends Specification {
|
||||
it.hash = BlockHash.from("0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec891521a")
|
||||
it.totalDifficulty = new BigInteger("35bbde5595de6455", 16)
|
||||
it.timestamp = Instant.now()
|
||||
it.parentHash = parent
|
||||
return it
|
||||
}
|
||||
api.answer("eth_getBlockByHash", [block1.hash.toHex(), false], block1)
|
||||
@@ -139,6 +144,7 @@ class EthereumGrpcUpstreamSpec extends Specification {
|
||||
BlockchainOuterClass.ChainHead.newBuilder()
|
||||
.setBlockId(block1.hash.toHex().substring(2))
|
||||
.setHeight(block1.number)
|
||||
.setParentBlockId(parent.toHex().substring(2))
|
||||
.setWeight(ByteString.copyFrom(block1.totalDifficulty.toByteArray()))
|
||||
.build()
|
||||
)
|
||||
@@ -147,6 +153,7 @@ class EthereumGrpcUpstreamSpec extends Specification {
|
||||
BlockchainOuterClass.ChainHead.newBuilder()
|
||||
.setBlockId(block2.hash.toHex().substring(2))
|
||||
.setHeight(block2.number)
|
||||
.setParentBlockId(parent.toHex().substring(2))
|
||||
.setWeight(ByteString.copyFrom(block2.totalDifficulty.toByteArray()))
|
||||
.build()
|
||||
)
|
||||
@@ -185,6 +192,7 @@ class EthereumGrpcUpstreamSpec extends Specification {
|
||||
it.hash = BlockHash.from("0x50d26e119968e791970d84a7bf5d0ec474d3ec2ef85d5ec8915210ac6bc09ad7")
|
||||
it.totalDifficulty = new BigInteger("35bbde5595de6456", 16)
|
||||
it.timestamp = Instant.now()
|
||||
it.parentHash = parent
|
||||
return it
|
||||
}
|
||||
def block2 = new BlockJson().with {
|
||||
@@ -192,6 +200,7 @@ class EthereumGrpcUpstreamSpec extends Specification {
|
||||
it.hash = BlockHash.from("0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec891521a")
|
||||
it.totalDifficulty = new BigInteger("35bbde5595de6457", 16)
|
||||
it.timestamp = Instant.now()
|
||||
it.parentHash = parent
|
||||
return it
|
||||
}
|
||||
api.answer("eth_getBlockByHash", [block1.hash.toHex(), false], block1)
|
||||
@@ -208,6 +217,7 @@ class EthereumGrpcUpstreamSpec extends Specification {
|
||||
BlockchainOuterClass.ChainHead.newBuilder()
|
||||
.setBlockId(block1.hash.toHex().substring(2))
|
||||
.setHeight(block1.number)
|
||||
.setParentBlockId(parent.toHex().substring(2))
|
||||
.setWeight(ByteString.copyFrom(block1.totalDifficulty.toByteArray()))
|
||||
.build()
|
||||
)
|
||||
@@ -215,6 +225,7 @@ class EthereumGrpcUpstreamSpec extends Specification {
|
||||
BlockchainOuterClass.ChainHead.newBuilder()
|
||||
.setBlockId(block2.hash.toHex().substring(2))
|
||||
.setHeight(block2.number)
|
||||
.setParentBlockId(parent.toHex().substring(2))
|
||||
.setWeight(ByteString.copyFrom(block2.totalDifficulty.toByteArray()))
|
||||
.build()
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user