Skip to content

Commit

Permalink
feat: use LineaRollupSmartContractClientReadOnly client for last fina…
Browse files Browse the repository at this point in the history
…lized block
  • Loading branch information
jonesho committed Jan 8, 2025
1 parent d1a1fec commit 9775ea7
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import kotlinx.datetime.Clock
import linea.encoding.BlockRLPEncoder
import net.consensys.linea.BlockNumberAndHash
import net.consensys.linea.blob.ShnarfCalculatorVersion
import net.consensys.linea.contract.LineaRollupAsyncFriendly
import net.consensys.linea.contract.Web3JL2MessageService
import net.consensys.linea.contract.Web3JL2MessageServiceLogsClient
import net.consensys.linea.contract.Web3JLogsClient
Expand Down Expand Up @@ -220,20 +219,19 @@ class L1DependentApp(
)
)

private val l1FinalizationMonitor = run {
// To avoid setDefaultBlockParameter clashes
val contractClient: LineaRollupSmartContractClientReadOnly = Web3JLineaRollupSmartContractClientReadOnly(
contractAddress = configs.l1.zkEvmContractAddress,
web3j = l1Web3jClient
)
private val lineaRollupClient: LineaRollupSmartContractClientReadOnly = Web3JLineaRollupSmartContractClientReadOnly(
contractAddress = configs.l1.zkEvmContractAddress,
web3j = l1Web3jClient
)

private val l1FinalizationMonitor = run {
FinalizationMonitorImpl(
config =
FinalizationMonitorImpl.Config(
pollingInterval = configs.l1.finalizationPollingInterval.toKotlinDuration(),
l1QueryBlockTag = configs.l1.l1QueryBlockTag
),
contract = contractClient,
contract = lineaRollupClient,
l2Client = l2Web3jClient,
vertx = vertx
)
Expand Down Expand Up @@ -922,17 +920,9 @@ class L1DependentApp(
}

private fun lastFinalizedBlock(): SafeFuture<ULong> {
val zkEvmClient: LineaRollupAsyncFriendly = instantiateZkEvmContractClient(
configs.l1,
finalizationTransactionManager,
feesFetcher,
l1MinPriorityFeeCalculator,
l1Web3jClient,
smartContractErrors
)
val l1BasedLastFinalizedBlockProvider = L1BasedLastFinalizedBlockProvider(
vertx,
zkEvmClient,
lineaRollupClient,
configs.conflation.consistentNumberOfBlocksOnL1ToWait.toUInt()
)
return l1BasedLastFinalizedBlockProvider.getLastFinalizedBlock()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package net.consensys.zkevm.coordinator.app

import build.linea.contract.LineaRollupV5
import build.linea.contract.l1.LineaRollupSmartContractClientReadOnly
import io.vertx.core.Vertx
import net.consensys.linea.BlockParameter
import net.consensys.linea.async.AsyncRetryer
import net.consensys.toULong
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
import org.web3j.protocol.core.DefaultBlockParameterName
import tech.pegasys.teku.infrastructure.async.SafeFuture
import java.math.BigInteger
import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.atomic.AtomicReference
import kotlin.time.Duration
Expand All @@ -26,19 +24,17 @@ interface LastFinalizedBlockProvider {
*/
class L1BasedLastFinalizedBlockProvider(
private val vertx: Vertx,
private val lineaRollupSmartContractWeb3jClient: LineaRollupV5,
private val lineaRollupSmartContractClient: LineaRollupSmartContractClientReadOnly,
private val consistentNumberOfBlocksOnL1: UInt,
private val numberOfRetries: UInt = Int.MAX_VALUE.toUInt(),
private val pollingInterval: Duration = 2.seconds
) : LastFinalizedBlockProvider {
private val log: Logger = LogManager.getLogger(this::class.java)

override fun getLastFinalizedBlock(): SafeFuture<ULong> {
lineaRollupSmartContractWeb3jClient.setDefaultBlockParameter(DefaultBlockParameterName.LATEST)

val lastObservedBlock = AtomicReference<BigInteger>(null)
val lastObservedBlock = AtomicReference<ULong>(null)
val numberOfObservations = AtomicInteger(1)
val isConsistentEnough = { lastPolledBlockNumber: BigInteger ->
val isConsistentEnough = { lastPolledBlockNumber: ULong ->
if (lastPolledBlockNumber == lastObservedBlock.get()) {
numberOfObservations.incrementAndGet().toUInt() >= consistentNumberOfBlocksOnL1
} else {
Expand All @@ -60,8 +56,9 @@ class L1BasedLastFinalizedBlockProvider(
backoffDelay = pollingInterval,
stopRetriesPredicate = isConsistentEnough
) {
SafeFuture.of(lineaRollupSmartContractWeb3jClient.currentL2BlockNumber().sendAsync())
lineaRollupSmartContractClient.finalizedL2BlockNumber(
blockParameter = BlockParameter.Tag.LATEST
)
}
.thenApply { it.toULong() }
}
}
Original file line number Diff line number Diff line change
@@ -1,54 +1,44 @@
package net.consensys.zkevm.coordinator.app

import build.linea.contract.LineaRollupV5
import build.linea.contract.l1.LineaRollupSmartContractClientReadOnly
import io.vertx.core.Vertx
import net.consensys.linea.BlockParameter
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.kotlin.doReturn
import org.mockito.Mockito
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import org.web3j.protocol.core.RemoteFunctionCall
import java.math.BigInteger
import java.util.concurrent.CompletableFuture
import tech.pegasys.teku.infrastructure.async.SafeFuture
import kotlin.time.Duration.Companion.milliseconds

class L1BasedLastFinalizedBlockProviderTest {
private lateinit var lineaRollupSmartContractWeb3jClient: LineaRollupV5
private lateinit var lineaRollupClient: LineaRollupSmartContractClientReadOnly

@BeforeEach
fun beforeEach() {
lineaRollupSmartContractWeb3jClient = mock()
lineaRollupClient =
mock<LineaRollupSmartContractClientReadOnly>(defaultAnswer = Mockito.RETURNS_DEEP_STUBS)
}

@Test
fun `shall wait number of blocks before returning for consistency`() {
val replies = listOf(
mockRemoteFnCallWithBlockNumber(100),
mockRemoteFnCallWithBlockNumber(100),
mockRemoteFnCallWithBlockNumber(101),
mockRemoteFnCallWithBlockNumber(101),
mockRemoteFnCallWithBlockNumber(101),
mockRemoteFnCallWithBlockNumber(101)
)
whenever(lineaRollupSmartContractWeb3jClient.currentL2BlockNumber())
.thenReturn(replies[0], *replies.subList(1, replies.size).toTypedArray())
val replies = listOf(100UL, 100UL, 101UL, 101UL, 101UL, 101UL)
whenever(lineaRollupClient.finalizedL2BlockNumber(eq(BlockParameter.Tag.LATEST)))
.thenReturn(
SafeFuture.completedFuture(replies[0]),
*replies.subList(1, replies.size).map { SafeFuture.completedFuture(it) }.toTypedArray()
)

val resumerCalculator = L1BasedLastFinalizedBlockProvider(
Vertx.vertx(),
lineaRollupSmartContractWeb3jClient,
lineaRollupClient,
consistentNumberOfBlocksOnL1 = 3u,
numberOfRetries = 50u,
pollingInterval = 10.milliseconds
)

assertThat(resumerCalculator.getLastFinalizedBlock().get()).isEqualTo(101.toULong())
}

private fun mockRemoteFnCallWithBlockNumber(blockNumber: Long): RemoteFunctionCall<BigInteger> {
return mock<RemoteFunctionCall<BigInteger>>() {
on { send() } doReturn (BigInteger.valueOf(blockNumber))
on { sendAsync() } doReturn (CompletableFuture.completedFuture(BigInteger.valueOf(blockNumber)))
}
}
}

0 comments on commit 9775ea7

Please sign in to comment.