-
Notifications
You must be signed in to change notification settings - Fork 127
L1 Data submission config and validium blob submitter #1788
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: validium_submitter
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,8 +15,28 @@ data class L1SubmissionConfigToml( | |
| val fallbackGasPrice: FallbackGasPriceToml, | ||
| val blob: BlobSubmissionConfigToml, | ||
| val aggregation: AggregationSubmissionToml, | ||
| val dataSubmission: DataSubmission = DataSubmission.ROLLUP, | ||
| ) { | ||
|
|
||
| enum class DataSubmission(val mame: String) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. typo?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, |
||
| ROLLUP("rollup"), | ||
| VALIDIUM("validium"), | ||
| ; | ||
|
|
||
| companion object { | ||
| fun valueOfIgnoreCase(name: String): DataSubmission { | ||
| return DataSubmission.entries.firstOrNull { it.name.equals(name, ignoreCase = true) } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: Unused property in DataSubmission enumThe
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please address this. Also, I don't thing we need the name property...
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok, I was just following what was done for a similar TOML config enum SignerType |
||
| ?: throw IllegalArgumentException("Unknown data submission type: $name") | ||
| } | ||
| } | ||
| fun reified(): L1SubmissionConfig.DataSubmission { | ||
| return when (this) { | ||
| ROLLUP -> L1SubmissionConfig.DataSubmission.ROLLUP | ||
| VALIDIUM -> L1SubmissionConfig.DataSubmission.VALIDIUM | ||
| } | ||
| } | ||
| } | ||
|
|
||
| data class DynamicGasPriceCapToml( | ||
| val disabled: Boolean = false, | ||
| val gasPriceCapCalculation: GasPriceCapCalculationToml, | ||
|
|
@@ -167,6 +187,7 @@ data class L1SubmissionConfigToml( | |
| gas = this.aggregation.gas.reified(), | ||
| signer = this.aggregation.signer.reified(), | ||
| ), | ||
| dataSubmission = this.dataSubmission.reified(), | ||
| ) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ import com.sksamuel.hoplite.StringNode | |
| import com.sksamuel.hoplite.decoder.Decoder | ||
| import com.sksamuel.hoplite.fp.invalid | ||
| import com.sksamuel.hoplite.fp.valid | ||
| import linea.coordinator.config.v2.toml.L1SubmissionConfigToml | ||
| import linea.coordinator.config.v2.toml.SignerConfigToml | ||
| import linea.kotlin.decodeHex | ||
| import kotlin.reflect.KType | ||
|
|
@@ -81,3 +82,28 @@ class TomlSignerTypeDecoder : Decoder<SignerConfigToml.SignerType> { | |
| return type.classifier == SignerConfigToml.SignerType::class | ||
| } | ||
| } | ||
|
|
||
| class TomlDataSubmissionDecoder : Decoder<L1SubmissionConfigToml.DataSubmission> { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do we need a specific decoder. Toml library shall handle that out for the box, no?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, i did not experiment with enum and toml library, I just followed a similar pattern we have for SignerType. You can notice the |
||
| override fun decode( | ||
| node: Node, | ||
| type: KType, | ||
| context: DecoderContext, | ||
| ): ConfigResult<L1SubmissionConfigToml.DataSubmission> { | ||
| return when (node) { | ||
| is StringNode -> runCatching { | ||
| L1SubmissionConfigToml.DataSubmission.valueOfIgnoreCase(node.value.lowercase()) | ||
| }.fold( | ||
| { it.valid() }, | ||
| { ConfigFailure.DecodeError(node, type).invalid() }, | ||
| ) | ||
|
|
||
| else -> { | ||
| ConfigFailure.DecodeError(node, type).invalid() | ||
| } | ||
| } | ||
| } | ||
|
|
||
| override fun supports(type: KType): Boolean { | ||
| return type.classifier == L1SubmissionConfigToml.DataSubmission::class | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,12 +4,15 @@ import io.vertx.core.Vertx | |
| import io.vertx.core.http.HttpVersion | ||
| import io.vertx.core.net.PfxOptions | ||
| import io.vertx.ext.web.client.WebClientOptions | ||
| import linea.coordinator.config.v2.SignerConfig | ||
| import linea.kotlin.encodeHex | ||
| import linea.web3j.SmartContractErrors | ||
| import linea.web3j.transactionmanager.AsyncFriendlyTransactionManager | ||
| import net.consensys.linea.contract.l1.Web3JLineaRollupSmartContractClient | ||
| import net.consensys.linea.contract.l1.Web3JLineaValidiumSmartContractClient | ||
| import net.consensys.linea.httprest.client.VertxHttpRestClient | ||
| import net.consensys.zkevm.coordinator.clients.smartcontract.LineaRollupSmartContractClient | ||
| import net.consensys.zkevm.coordinator.clients.smartcontract.LineaValidiumSmartContractClient | ||
| import net.consensys.zkevm.ethereum.crypto.Web3SignerRestClient | ||
| import net.consensys.zkevm.ethereum.crypto.Web3SignerTxSignService | ||
| import net.consensys.zkevm.ethereum.signing.ECKeypairSignerAdapter | ||
|
|
@@ -27,7 +30,7 @@ import javax.net.ssl.TrustManagerFactory | |
|
|
||
| fun createTransactionManager( | ||
| vertx: Vertx, | ||
| signerConfig: linea.coordinator.config.v2.SignerConfig, | ||
| signerConfig: SignerConfig, | ||
| client: Web3j, | ||
| ): AsyncFriendlyTransactionManager { | ||
| fun loadKeyAndTrustStoreFromFiles( | ||
|
|
@@ -78,11 +81,11 @@ fun createTransactionManager( | |
| } | ||
|
|
||
| val transactionSignService = when (signerConfig.type) { | ||
| linea.coordinator.config.v2.SignerConfig.SignerType.WEB3J -> { | ||
| SignerConfig.SignerType.WEB3J -> { | ||
| TxSignServiceImpl(Credentials.create(signerConfig.web3j!!.privateKey.encodeHex())) | ||
| } | ||
|
|
||
| linea.coordinator.config.v2.SignerConfig.SignerType.WEB3SIGNER -> { | ||
| SignerConfig.SignerType.WEB3SIGNER -> { | ||
| val web3SignerConfig = signerConfig.web3signer!! | ||
| val endpoint = web3SignerConfig.endpoint | ||
| val webClientOptions: WebClientOptions = | ||
|
|
@@ -131,3 +134,21 @@ fun createLineaRollupContractClient( | |
| useEthEstimateGas = useEthEstimateGas, | ||
| ) | ||
| } | ||
|
|
||
| fun createLineaValidiumContractClient( | ||
| contractAddress: String, | ||
| transactionManager: AsyncFriendlyTransactionManager, | ||
| contractGasProvider: ContractGasProvider, | ||
| web3jClient: Web3j, | ||
| smartContractErrors: SmartContractErrors, | ||
| useEthEstimateGas: Boolean, | ||
| ): LineaValidiumSmartContractClient { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this looks duplicated. Have you considered
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that is better. |
||
| return Web3JLineaValidiumSmartContractClient.load( | ||
| contractAddress = contractAddress, | ||
| web3j = web3jClient, | ||
| transactionManager = transactionManager, | ||
| contractGasProvider = contractGasProvider, | ||
| smartContractErrors = smartContractErrors, | ||
| useEthEstimateGas = useEthEstimateGas, | ||
| ) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ import linea.contract.l1.LineaRollupSmartContractClientReadOnly | |
| import linea.contract.l1.Web3JLineaRollupSmartContractClientReadOnly | ||
| import linea.coordinator.config.toJsonRpcRetry | ||
| import linea.coordinator.config.v2.CoordinatorConfig | ||
| import linea.coordinator.config.v2.L1SubmissionConfig | ||
| import linea.coordinator.config.v2.Type2StateProofManagerConfig | ||
| import linea.coordinator.config.v2.isDisabled | ||
| import linea.coordinator.config.v2.isEnabled | ||
|
|
@@ -46,6 +47,7 @@ import net.consensys.zkevm.coordinator.app.conflation.ConflationApp | |
| import net.consensys.zkevm.coordinator.app.conflation.ConflationAppHelper.resumeConflationFrom | ||
| import net.consensys.zkevm.coordinator.clients.ShomeiClient | ||
| import net.consensys.zkevm.coordinator.clients.smartcontract.LineaRollupSmartContractClient | ||
| import net.consensys.zkevm.coordinator.clients.smartcontract.LineaSmartContractClient | ||
| import net.consensys.zkevm.domain.BlobSubmittedEvent | ||
| import net.consensys.zkevm.domain.FinalizationSubmittedEvent | ||
| import net.consensys.zkevm.ethereum.coordination.EventDispatcher | ||
|
|
@@ -294,7 +296,7 @@ class L1DependentApp( | |
| lastFinalizedBlock, | ||
| ).get() | ||
|
|
||
| private val lineaSmartContractClientForDataSubmission: LineaRollupSmartContractClient = run { | ||
| private val lineaSmartContractClientForDataSubmission: LineaSmartContractClient = run { | ||
| // The below gas provider will act as the primary gas provider if L1 | ||
| // dynamic gas pricing is disabled and will act as a fallback gas provider | ||
| // if L1 dynamic gas pricing is enabled | ||
|
|
@@ -313,20 +315,32 @@ class L1DependentApp( | |
| rpcUrl = configs.l1Submission.blob.l1Endpoint.toString(), | ||
| log = LogManager.getLogger("clients.l1.eth.data-submission"), | ||
| ) | ||
| createLineaRollupContractClient( | ||
| contractAddress = configs.protocol.l1.contractAddress, | ||
| transactionManager = createTransactionManager( | ||
| vertx, | ||
| signerConfig = configs.l1Submission.blob.signer, | ||
| client = l1Web3jClient, | ||
| ), | ||
| contractGasProvider = primaryOrFallbackGasProvider, | ||
| web3jClient = l1Web3jClient, | ||
| smartContractErrors = smartContractErrors, | ||
| // eth_estimateGas would fail because we submit multiple blob tx | ||
| // and 2nd would fail with revert reason | ||
| useEthEstimateGas = false, | ||
| val transactionManager = createTransactionManager( | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: Null pointer exception for Validium blob gas capThe code force-unwraps Additional Locations (1) |
||
| vertx, | ||
| signerConfig = configs.l1Submission.blob.signer, | ||
| client = l1Web3jClient, | ||
| ) | ||
| when (configs.l1Submission.dataSubmission) { | ||
| L1SubmissionConfig.DataSubmission.ROLLUP -> createLineaRollupContractClient( | ||
| contractAddress = configs.protocol.l1.contractAddress, | ||
| transactionManager = transactionManager, | ||
| contractGasProvider = primaryOrFallbackGasProvider, | ||
| web3jClient = l1Web3jClient, | ||
| smartContractErrors = smartContractErrors, | ||
| // eth_estimateGas would fail because we submit multiple blob tx | ||
| // and 2nd would fail with revert reason | ||
| useEthEstimateGas = false, | ||
| ) | ||
|
|
||
| L1SubmissionConfig.DataSubmission.VALIDIUM -> createLineaValidiumContractClient( | ||
| contractAddress = configs.protocol.l1.contractAddress, | ||
| transactionManager = transactionManager, | ||
| contractGasProvider = primaryOrFallbackGasProvider, | ||
| web3jClient = l1Web3jClient, | ||
| smartContractErrors = smartContractErrors, | ||
| useEthEstimateGas = false, | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| private val highestAcceptedBlobTracker = HighestULongTracker(lastProcessedBlockNumber).also { | ||
|
|
@@ -340,7 +354,7 @@ class L1DependentApp( | |
|
|
||
| private val alreadySubmittedBlobsFilter = | ||
| L1ShnarfBasedAlreadySubmittedBlobsFilter( | ||
| lineaRollup = lineaSmartContractClientForDataSubmission, | ||
| lineaSmartContractClientReadOnly = lineaSmartContractClientForDataSubmission, | ||
| acceptedBlobEndBlockNumberConsumer = { highestAcceptedBlobTracker(it) }, | ||
| ) | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,6 +19,7 @@ class L1SubmissionConfigParsingTest { | |
| val toml = """ | ||
| [l1-submission] | ||
| disabled = true | ||
| data-submission = "validium" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In our meeting with @julien-marchand we agreed on this config layout What's the motivation/rationale to:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| [l1-submission.dynamic-gas-price-cap] | ||
| disabled = true | ||
| [l1-submission.dynamic-gas-price-cap.gas-price-cap-calculation] | ||
|
|
@@ -118,6 +119,7 @@ class L1SubmissionConfigParsingTest { | |
| val config = | ||
| L1SubmissionConfigToml( | ||
| disabled = true, | ||
| dataSubmission = L1SubmissionConfigToml.DataSubmission.VALIDIUM, | ||
| dynamicGasPriceCap = L1SubmissionConfigToml.DynamicGasPriceCapToml( | ||
| disabled = true, | ||
| gasPriceCapCalculation = L1SubmissionConfigToml.DynamicGasPriceCapToml.GasPriceCapCalculationToml( | ||
|
|
@@ -377,6 +379,7 @@ class L1SubmissionConfigParsingTest { | |
|
|
||
| @Test | ||
| fun `should parse l1 submission minimal config`() { | ||
| assertThat(parseConfig<WrapperConfig>(tomlMinimal).l1Submission).isEqualTo(configMinimal) | ||
| val config = parseConfig<WrapperConfig>(tomlMinimal) | ||
| assertThat(config.l1Submission).isEqualTo(configMinimal) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| package net.consensys.linea.contract.l1 | ||
|
|
||
| import build.linea.contract.ValidiumV1 | ||
| import linea.web3j.transactionmanager.AsyncFriendlyTransactionManager | ||
| import net.consensys.linea.contract.Web3JContractAsyncHelper | ||
| import org.web3j.abi.datatypes.Function | ||
| import org.web3j.protocol.Web3j | ||
| import org.web3j.protocol.core.RemoteFunctionCall | ||
| import org.web3j.protocol.core.methods.response.TransactionReceipt | ||
| import org.web3j.tx.gas.ContractGasProvider | ||
| import java.math.BigInteger | ||
|
|
||
| internal class LineaValidiumEnhancedWrapper( | ||
| contractAddress: String, | ||
| web3j: Web3j, | ||
| transactionManager: AsyncFriendlyTransactionManager, | ||
| contractGasProvider: ContractGasProvider, | ||
| private val web3jContractHelper: Web3JContractAsyncHelper, | ||
| ) : ValidiumV1( | ||
| contractAddress, | ||
| web3j, | ||
| transactionManager, | ||
| contractGasProvider, | ||
| ) { | ||
| @Synchronized | ||
| override fun executeRemoteCallTransaction( | ||
| function: Function, | ||
| weiValue: BigInteger, | ||
| ): RemoteFunctionCall<TransactionReceipt> = web3jContractHelper.executeRemoteCallTransaction(function, weiValue) | ||
|
|
||
| @Synchronized | ||
| override fun executeRemoteCallTransaction( | ||
| function: Function, | ||
| ): RemoteFunctionCall<TransactionReceipt> = web3jContractHelper.executeRemoteCallTransaction( | ||
| function, | ||
| BigInteger.ZERO, | ||
| ) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DataSubmission is not appropriate IMO
suggestions:
@julien-marchand any inputs on this?
This will have impact on logic/proving once filly implemented