diff --git a/hildr-batcher/src/main/java/io/optimism/batcher/BatcherSubmitter.java b/hildr-batcher/src/main/java/io/optimism/batcher/BatcherSubmitter.java index 04728ce9..6b5f7a99 100644 --- a/hildr-batcher/src/main/java/io/optimism/batcher/BatcherSubmitter.java +++ b/hildr-batcher/src/main/java/io/optimism/batcher/BatcherSubmitter.java @@ -27,7 +27,6 @@ import io.optimism.batcher.publisher.ChannelDataPublisher; import io.optimism.batcher.publisher.PublisherConfig; import io.optimism.type.BlockId; -import io.optimism.type.L1BlockRef; import io.optimism.utilities.derive.stages.Frame; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,8 +51,6 @@ public class BatcherSubmitter extends AbstractExecutionThreadService { private volatile boolean isShutdownTriggered = false; - private L1BlockRef lastL1Tip; - /** * Constructor of BatcherSubmitter. * diff --git a/hildr-batcher/src/main/java/io/optimism/batcher/channel/ChannelConfig.java b/hildr-batcher/src/main/java/io/optimism/batcher/channel/ChannelConfig.java index dd42cbca..6b2ad844 100644 --- a/hildr-batcher/src/main/java/io/optimism/batcher/channel/ChannelConfig.java +++ b/hildr-batcher/src/main/java/io/optimism/batcher/channel/ChannelConfig.java @@ -17,6 +17,7 @@ package io.optimism.batcher.channel; import io.optimism.batcher.config.Config; +import io.optimism.batcher.telemetry.BatcherMetrics; /** * ChannelConfig class. @@ -27,6 +28,7 @@ * @param maxFrameSize The maximum byte-size a frame can have. * @param seqWindowSize The maximum byte-size a frame can have. * @param subSafetyMargin The maximum byte-size a frame can have. + * @param metrics Batcher metrics * @author thinkAfCod * @since 0.1.1 */ @@ -35,7 +37,8 @@ public record ChannelConfig( long maxChannelDuration, int maxFrameSize, long seqWindowSize, - long subSafetyMargin) { + long subSafetyMargin, + BatcherMetrics metrics) { /** * Create a ChannelConfig instance from Config instance. @@ -44,6 +47,6 @@ public record ChannelConfig( * @return ChannelConfig instance */ public static ChannelConfig from(Config config) { - return new ChannelConfig(30000, 0, 120_000, 3600, 10); + return new ChannelConfig(30000, 0, 120_000, 3600, 10, config.metrics()); } } diff --git a/hildr-batcher/src/main/java/io/optimism/batcher/channel/ChannelImpl.java b/hildr-batcher/src/main/java/io/optimism/batcher/channel/ChannelImpl.java index d5b1cd85..a492f6e6 100644 --- a/hildr-batcher/src/main/java/io/optimism/batcher/channel/ChannelImpl.java +++ b/hildr-batcher/src/main/java/io/optimism/batcher/channel/ChannelImpl.java @@ -18,6 +18,7 @@ import io.optimism.batcher.compressor.Compressor; import io.optimism.batcher.exception.UnsupportedException; +import io.optimism.batcher.telemetry.BatcherMetrics; import io.optimism.type.BlockId; import io.optimism.type.L1BlockInfo; import io.optimism.utilities.derive.stages.Batch; @@ -58,25 +59,27 @@ public class ChannelImpl implements Channel { private final ChannelConfig chConfig; + private final BatcherMetrics metrics; + private final BigInteger seqWindowTimeout; private final BigInteger id; - private AtomicInteger frameNumber; + private final AtomicInteger frameNumber; - private List outputFrames; + private final List outputFrames; - private Map pendingTxs; + private final Map pendingTxs; - private Map confirmedTxs; + private final Map confirmedTxs; - private List blocks; + private final List blocks; private BigInteger timeoutBlock; - private Compressor compressor; + private final Compressor compressor; - private AtomicInteger rlpLength; + private final AtomicInteger rlpLength; private volatile boolean isFull; @@ -90,6 +93,7 @@ public class ChannelImpl implements Channel { */ public ChannelImpl(ChannelConfig chConfig, Compressor compressor) { this.chConfig = chConfig; + this.metrics = chConfig.metrics(); this.seqWindowTimeout = BigInteger.valueOf(chConfig.seqWindowSize() - chConfig.subSafetyMargin()); this.compressor = compressor; @@ -175,7 +179,7 @@ public boolean hasFrame() { @Override public void txFailed(Frame tx) { - // todo metrics record batch tx failed. + this.metrics.recordBatchTxFailed(); var code = tx.code(); if (!this.pendingTxs.containsKey(code)) { LOGGER.warn( @@ -190,7 +194,7 @@ public void txFailed(Frame tx) { @Override public List txConfirmed(Frame tx, BlockId inclusionBlock) { - // todo metrics RecordBatchTxSubmitted + this.metrics.recordBatchTxSubmitted(); LOGGER.debug( "marked tx as confirmed: chId: {}; frameNum: {}; block: {}", tx.channelId(), @@ -214,12 +218,12 @@ public List txConfirmed(Frame tx, BlockId inclusionBlock) { .subtract(BigInteger.valueOf(chConfig.subSafetyMargin())); this.updateTimeout(timeout); if (this.isTimeout()) { - // todo metrics recordChannelTimeout + this.metrics.recordChannelTimedOut(tx); LOGGER.warn("Channel timeout: chId:{}", tx.channelId()); return this.blocks; } if (this.isFullySubmitted()) { - // todo metrics RecordChannelFullySubmitted + this.metrics.recordChannelFullySubmitted(tx); LOGGER.info("Channel is fully submitted: chId:{}", tx.channelId()); } return null; diff --git a/hildr-batcher/src/main/java/io/optimism/batcher/channel/ChannelManager.java b/hildr-batcher/src/main/java/io/optimism/batcher/channel/ChannelManager.java index 27086eb4..959b1943 100644 --- a/hildr-batcher/src/main/java/io/optimism/batcher/channel/ChannelManager.java +++ b/hildr-batcher/src/main/java/io/optimism/batcher/channel/ChannelManager.java @@ -18,6 +18,7 @@ import io.optimism.batcher.compressor.CompressorConfig; import io.optimism.batcher.compressor.Compressors; +import io.optimism.batcher.telemetry.BatcherMetrics; import io.optimism.type.BlockId; import io.optimism.type.L1BlockInfo; import io.optimism.type.L2BlockRef; @@ -45,6 +46,8 @@ public class ChannelManager { private final ChannelConfig chConfig; + private final BatcherMetrics metrics; + private final CompressorConfig compressorConfig; private List blocks; @@ -67,6 +70,7 @@ public class ChannelManager { */ public ChannelManager(final ChannelConfig chConfig, final CompressorConfig compressorConfig) { this.chConfig = chConfig; + this.metrics = chConfig.metrics(); this.compressorConfig = compressorConfig; this.blocks = new ArrayList<>(256); this.channels = new ArrayList<>(256); @@ -85,9 +89,9 @@ public void addL2Block(EthBlock.Block block) { if (!StringUtils.isEmpty(latestBlockHash) && !latestBlockHash.equals(block.getParentHash())) { throw new ReorgException("block does not extend existing chain"); } - // todo metrics pending block this.blocks.add(block); this.latestBlockHash = block.getHash(); + this.metrics.recordL2BlockInPendingQueue(block); } /** @@ -155,7 +159,7 @@ public void txFailed(final Frame tx) { * @param inclusionBlock inclusion block id */ public void txConfirmed(final Frame tx, final BlockId inclusionBlock) { - // todo metrics RecordBatchTxSubmitted + this.metrics.recordBatchTxSubmitted(); LOGGER.debug( "marked transaction as confirmed: chId: {}; frameNum: {};block: {}", tx.channelId(), @@ -222,21 +226,21 @@ private Channel openChannel(final BlockId l1Head) { Channel ch = new ChannelImpl(this.chConfig, Compressors.create(this.compressorConfig)); LOGGER.info( "Created a channel: id:{}, l1Head: {}, blocksPending:{}", ch, l1Head, this.blocks.size()); - // todo metrics record opened channel + this.metrics.recordChannelOpened(null, this.blocks.size()); return ch; } private void pushBlocks(final Channel lastChannel) { int blocksAdded = 0; - L2BlockRef unused = null; + L2BlockRef l2Ref = null; try { for (final EthBlock.Block block : this.blocks) { final L1BlockInfo l1Info = lastChannel.addBlock(block); - unused = L2BlockRef.fromBlockAndL1Info(block, l1Info); - // todo metrics recordL2BlockInChannel + l2Ref = L2BlockRef.fromBlockAndL1Info(block, l1Info); if (latestChannel.isFull()) { break; } + this.metrics.recordL2BlockInChannel(block); blocksAdded += 1; } } catch (ChannelException e) { @@ -252,7 +256,12 @@ private void pushBlocks(final Channel lastChannel) { this.blocks = this.blocks.stream().skip(blocksAdded).collect(Collectors.toList()); } - // todo metrics RecordL2BlocksAdded + this.metrics.recordL2BlocksAdded( + l2Ref, + blocksAdded, + this.blocks.size(), + this.latestChannel.inputBytesLength(), + this.latestChannel.readyBytesLength()); LOGGER.debug( "Added blocks to channel:" diff --git a/hildr-batcher/src/main/java/io/optimism/batcher/config/Config.java b/hildr-batcher/src/main/java/io/optimism/batcher/config/Config.java index 79e16b99..20600777 100644 --- a/hildr-batcher/src/main/java/io/optimism/batcher/config/Config.java +++ b/hildr-batcher/src/main/java/io/optimism/batcher/config/Config.java @@ -16,6 +16,9 @@ package io.optimism.batcher.config; +import io.optimism.batcher.telemetry.BatcherMetrics; +import java.util.Objects; + /** * Batcher config. * @@ -27,9 +30,10 @@ * @param subSafetyMargin Sub-safety margin * @param pollInterval Milliseconds of poll interval * @param maxL1TxSize Max L1 Tx Size - * @param targetFrameSize Max L1 Tx Size - * @param targetNumFrames Max L1 Tx Size - * @param approxComprRatio Max L1 Tx Size + * @param targetFrameSize The target of frame size + * @param targetNumFrames The target of frame number + * @param approxComprRatio Compress ratio + * @param metrics Batcher metrics * @author thinkAfCod * @since 0.1.1 */ @@ -44,4 +48,81 @@ public record Config( Long maxL1TxSize, Integer targetFrameSize, Integer targetNumFrames, - String approxComprRatio) {} + String approxComprRatio, + BatcherMetrics metrics) { + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof Config that)) { + return false; + } + return Objects.equals(this.l1RpcUrl, that.l1RpcUrl) + && Objects.equals(this.l2RpcUrl, that.l2RpcUrl) + && Objects.equals(this.rollupRpcUrl, that.rollupRpcUrl) + && Objects.equals(this.l1Signer, that.l1Signer) + && Objects.equals(this.batchInboxAddress, that.batchInboxAddress) + && Objects.equals(this.subSafetyMargin, that.subSafetyMargin) + && Objects.equals(this.pollInterval, that.pollInterval) + && Objects.equals(this.maxL1TxSize, that.maxL1TxSize) + && Objects.equals(this.targetFrameSize, that.targetFrameSize) + && Objects.equals(this.targetNumFrames, that.targetNumFrames) + && Objects.equals(this.approxComprRatio, that.approxComprRatio); + } + + @Override + public int hashCode() { + return Objects.hash( + l1RpcUrl, + l2RpcUrl, + rollupRpcUrl, + l1Signer, + batchInboxAddress, + subSafetyMargin, + pollInterval, + maxL1TxSize, + targetFrameSize, + targetNumFrames, + approxComprRatio); + } + + @Override + public String toString() { + return "Config[" + + "l1RpcUrl=" + + l1RpcUrl + + ", " + + "l2RpcUrl=" + + l2RpcUrl + + ", " + + "rollupRpcUrl=" + + rollupRpcUrl + + ", " + + "l1Signer=" + + l1Signer + + ", " + + "batchInboxAddress=" + + batchInboxAddress + + ", " + + "subSafetyMargin=" + + subSafetyMargin + + ", " + + "pollInterval=" + + pollInterval + + ", " + + "maxL1TxSize=" + + maxL1TxSize + + ", " + + "targetFrameSize=" + + targetFrameSize + + ", " + + "targetNumFrames=" + + targetNumFrames + + ", " + + "approxComprRatio=" + + approxComprRatio + + ']'; + } +} diff --git a/hildr-batcher/src/main/java/io/optimism/batcher/loader/BlockLoader.java b/hildr-batcher/src/main/java/io/optimism/batcher/loader/BlockLoader.java index 531c55a8..bec49556 100644 --- a/hildr-batcher/src/main/java/io/optimism/batcher/loader/BlockLoader.java +++ b/hildr-batcher/src/main/java/io/optimism/batcher/loader/BlockLoader.java @@ -18,6 +18,7 @@ import io.optimism.batcher.channel.ReorgException; import io.optimism.batcher.exception.Web3jCallException; +import io.optimism.batcher.telemetry.BatcherMetrics; import io.optimism.type.BlockId; import io.optimism.type.Genesis; import io.optimism.type.L1BlockInfo; @@ -65,6 +66,8 @@ public class BlockLoader implements Closeable { private final Web3jService rollupService; + private final BatcherMetrics metrics; + private final Consumer blockConsumer; private BlockId latestLoadedBlock; @@ -75,13 +78,14 @@ public class BlockLoader implements Closeable { * Constructor of BlockLoader. * * @param config LoaderConfig instance - * @param blockConsumer consumer block loaded from L2 + * @param blockConsumer Consumer block loaded from L2 */ public BlockLoader(LoaderConfig config, Consumer blockConsumer) { this.l2Client = Web3jProvider.createClient(config.l2RpcUrl()); Tuple2 tuple = Web3jProvider.create(config.rollupUrl()); this.rollupClient = tuple.component1(); this.rollupService = tuple.component2(); + this.metrics = config.metrics(); this.blockConsumer = blockConsumer; this.rollupConfig = loadRollConfig(); } @@ -140,8 +144,8 @@ private void loadBlocksIntoState() { if (lastBlock == null) { throw new BlockLoaderException("get latest block failed"); } - var ignore = l2BlockToBlockRef(lastBlock, rollupConfig.genesis()); - // todo metrics.RecordL2BlocksLoaded l2Ref + var l2Ref = l2BlockToBlockRef(lastBlock, rollupConfig.genesis()); + this.metrics.recordL2BlocksLoaded(l2Ref); } private Tuple2 calculateL2BlockRangeToStore() { diff --git a/hildr-batcher/src/main/java/io/optimism/batcher/loader/LoaderConfig.java b/hildr-batcher/src/main/java/io/optimism/batcher/loader/LoaderConfig.java index 7b5a8d45..1c17cebd 100644 --- a/hildr-batcher/src/main/java/io/optimism/batcher/loader/LoaderConfig.java +++ b/hildr-batcher/src/main/java/io/optimism/batcher/loader/LoaderConfig.java @@ -17,16 +17,18 @@ package io.optimism.batcher.loader; import io.optimism.batcher.config.Config; +import io.optimism.batcher.telemetry.BatcherMetrics; /** * L2 loader config. * * @param l2RpcUrl L2 rpc url * @param rollupUrl op-rollup node url + * @param metrics Batcher metrics * @author thinkAfCod * @since 0.1.1 */ -public record LoaderConfig(String l2RpcUrl, String rollupUrl) { +public record LoaderConfig(String l2RpcUrl, String rollupUrl, BatcherMetrics metrics) { /** * Create a LoaderConfig instance from Config instance. @@ -35,6 +37,6 @@ public record LoaderConfig(String l2RpcUrl, String rollupUrl) { * @return LoaderConfig instance */ public static LoaderConfig from(Config config) { - return new LoaderConfig(config.l2RpcUrl(), config.rollupRpcUrl()); + return new LoaderConfig(config.l2RpcUrl(), config.rollupRpcUrl(), config.metrics()); } } diff --git a/hildr-batcher/src/main/java/io/optimism/batcher/publisher/ChannelDataPublisher.java b/hildr-batcher/src/main/java/io/optimism/batcher/publisher/ChannelDataPublisher.java index 2c1d1472..41c6fc80 100644 --- a/hildr-batcher/src/main/java/io/optimism/batcher/publisher/ChannelDataPublisher.java +++ b/hildr-batcher/src/main/java/io/optimism/batcher/publisher/ChannelDataPublisher.java @@ -17,6 +17,7 @@ package io.optimism.batcher.publisher; import io.optimism.batcher.exception.Web3jCallException; +import io.optimism.batcher.telemetry.BatcherMetrics; import io.optimism.type.BlockId; import io.optimism.type.L1BlockRef; import io.optimism.utilities.derive.stages.Frame; @@ -58,6 +59,8 @@ public class ChannelDataPublisher implements Closeable { private final PublisherConfig config; + private final BatcherMetrics metrics; + private final String fromAddress; private final Web3j l1Client; @@ -84,6 +87,7 @@ public ChannelDataPublisher( Function dataSupplier, BiConsumer txReceiptReturn) { this.config = config; + this.metrics = config.metrics(); this.l1Client = Web3jProvider.createClient(config.l1RpcUrl()); var credentials = Credentials.create(config.l1Signer()); this.fromAddress = credentials.getAddress(); @@ -196,7 +200,7 @@ private void recordL1Head(L1BlockRef headRef) { return; } this.lastL1Tip = headRef; - // todo metrics LatestL1Block + this.metrics.recordLatestL1Block(headRef); } private synchronized BigInteger nextNonce() { diff --git a/hildr-batcher/src/main/java/io/optimism/batcher/publisher/PublisherConfig.java b/hildr-batcher/src/main/java/io/optimism/batcher/publisher/PublisherConfig.java index 25bb1a48..21083bee 100644 --- a/hildr-batcher/src/main/java/io/optimism/batcher/publisher/PublisherConfig.java +++ b/hildr-batcher/src/main/java/io/optimism/batcher/publisher/PublisherConfig.java @@ -17,6 +17,7 @@ package io.optimism.batcher.publisher; import io.optimism.batcher.config.Config; +import io.optimism.batcher.telemetry.BatcherMetrics; import io.optimism.type.RollupConfigRes; import java.math.BigInteger; @@ -27,11 +28,16 @@ * @param l1Signer L1 signer private key * @param l1chainId L1 chain id * @param batchInboxAddress Address of BatchInboxContract on L1 + * @param metrics Batcher metrics * @author thinkAfCod * @since 0.1.1 */ public record PublisherConfig( - String l1RpcUrl, String l1Signer, BigInteger l1chainId, String batchInboxAddress) { + String l1RpcUrl, + String l1Signer, + BigInteger l1chainId, + String batchInboxAddress, + BatcherMetrics metrics) { /** * Create a PublisherConfig instance from Config instance. @@ -45,6 +51,7 @@ public static PublisherConfig from(Config config, RollupConfigRes.RollupConfig r config.l1RpcUrl(), config.l1Signer(), rollupConfig.l1ChainId(), - rollupConfig.batchInboxAddress()); + rollupConfig.batchInboxAddress(), + config.metrics()); } }