diff --git a/src/main/java/io/optimism/spec/derive/datasource/BlobProvider.java b/src/main/java/io/optimism/spec/derive/datasource/BlobProvider.java new file mode 100644 index 00000000..66d0629e --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/datasource/BlobProvider.java @@ -0,0 +1,12 @@ +package io.optimism.spec.derive.datasource; + +import io.optimism.types.BlobSidecar; +import io.optimism.types.BlockInfo; + +import java.util.List; + +public interface BlobProvider { + + BlobSidecar getBlobs(BlockInfo l1Info, List blobHashes); + +} diff --git a/src/main/java/io/optimism/spec/derive/datasource/ChainProvider.java b/src/main/java/io/optimism/spec/derive/datasource/ChainProvider.java new file mode 100644 index 00000000..f5e08d85 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/datasource/ChainProvider.java @@ -0,0 +1,19 @@ +package io.optimism.spec.derive.datasource; + +import io.optimism.types.BlockInfo; +import org.web3j.protocol.core.methods.response.EthBlock; +import org.web3j.protocol.core.methods.response.TransactionReceipt; + +import java.math.BigInteger; + +public interface ChainProvider { + + EthBlock.Block headerByHash(String hash); + + BlockInfo blockInfoByNumber(BigInteger num); + + TransactionReceipt receiptsByHash(String hash); + + EthBlock.Block blockInfoNTxsByHash(String hash); + +} diff --git a/src/main/java/io/optimism/spec/derive/datasource/DataAvailabilityProvider.java b/src/main/java/io/optimism/spec/derive/datasource/DataAvailabilityProvider.java new file mode 100644 index 00000000..d15580ce --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/datasource/DataAvailabilityProvider.java @@ -0,0 +1,10 @@ +package io.optimism.spec.derive.datasource; + +import io.optimism.spec.derive.stages.DataIter; +import io.optimism.types.BlockInfo; + +public interface DataAvailabilityProvider { + + DataIter openData(BlockInfo l1Ref, String batcherAddr); + +} diff --git a/src/main/java/io/optimism/spec/derive/datasource/L2ChainProvider.java b/src/main/java/io/optimism/spec/derive/datasource/L2ChainProvider.java new file mode 100644 index 00000000..35143856 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/datasource/L2ChainProvider.java @@ -0,0 +1,18 @@ +package io.optimism.spec.derive.datasource; + +import io.optimism.config.Config; +import io.optimism.types.ExecutionPayloadEnvelop; +import io.optimism.types.L2BlockRef; +import io.optimism.types.SystemConfig; + +import java.math.BigInteger; + +public interface L2ChainProvider { + + L2BlockRef l2BlockInfoByNumber(BigInteger num); + + ExecutionPayloadEnvelop payloadByNumber(BigInteger num); + + SystemConfig systemConfigByNumber(BigInteger num, Config.ChainConfig chainConfig); + +} diff --git a/src/main/java/io/optimism/spec/derive/datasource/impl/L1Retrieval.java b/src/main/java/io/optimism/spec/derive/datasource/impl/L1Retrieval.java new file mode 100644 index 00000000..96e21213 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/datasource/impl/L1Retrieval.java @@ -0,0 +1,31 @@ +package io.optimism.spec.derive.datasource.impl; + +import io.optimism.config.Config; +import io.optimism.spec.derive.stages.FrameQueueProvider; +import io.optimism.spec.derive.stages.OriginAdvancer; +import io.optimism.spec.derive.stages.OriginProvider; +import io.optimism.spec.derive.stages.ResettableStage; +import io.optimism.types.BlockInfo; + +public class L1Retrieval implements FrameQueueProvider, OriginProvider, OriginAdvancer, ResettableStage { + + @Override + public void advanceOrigin() { + + } + + @Override + public BlockInfo origin() { + return null; + } + + @Override + public void reset(BlockInfo base, Config.SystemConfig config) { + + } + + @Override + public byte[] next() { + return new byte[0]; + } +} diff --git a/src/main/java/io/optimism/spec/derive/datasource/impl/L1Traversal.java b/src/main/java/io/optimism/spec/derive/datasource/impl/L1Traversal.java new file mode 100644 index 00000000..c99bb6f7 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/datasource/impl/L1Traversal.java @@ -0,0 +1,41 @@ +package io.optimism.spec.derive.datasource.impl; + +import io.optimism.config.Config; +import io.optimism.spec.derive.stages.L1RetrievalProvider; +import io.optimism.spec.derive.stages.OriginAdvancer; +import io.optimism.spec.derive.stages.OriginProvider; +import io.optimism.spec.derive.stages.ResettableStage; +import io.optimism.types.BlockInfo; + +public class L1Traversal implements L1RetrievalProvider, OriginProvider, OriginAdvancer, ResettableStage { + + public L1Traversal() { + + } + + + @Override + public BlockInfo nextL1Block() { + return null; + } + + @Override + public String batcherAddr() { + return ""; + } + + @Override + public void advanceOrigin() { + + } + + @Override + public BlockInfo origin() { + return null; + } + + @Override + public void reset(BlockInfo base, Config.SystemConfig config) { + + } +} diff --git a/src/main/java/io/optimism/spec/derive/pipeline/DerivationPipeline.java b/src/main/java/io/optimism/spec/derive/pipeline/DerivationPipeline.java new file mode 100644 index 00000000..d078aa94 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/pipeline/DerivationPipeline.java @@ -0,0 +1,7 @@ +package io.optimism.spec.derive.pipeline; + +public class DerivationPipeline { + + DerivationPipeline() {} + +} diff --git a/src/main/java/io/optimism/spec/derive/pipeline/PipelineBuilder.java b/src/main/java/io/optimism/spec/derive/pipeline/PipelineBuilder.java new file mode 100644 index 00000000..46521658 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/pipeline/PipelineBuilder.java @@ -0,0 +1,11 @@ +package io.optimism.spec.derive.pipeline; + +public class PipelineBuilder { + + public PipelineBuilder() {} + + public DerivationPipeline build() { + return new DerivationPipeline(); + } + +} diff --git a/src/main/java/io/optimism/spec/derive/stages/AttributesBuilder.java b/src/main/java/io/optimism/spec/derive/stages/AttributesBuilder.java new file mode 100644 index 00000000..90340448 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/stages/AttributesBuilder.java @@ -0,0 +1,11 @@ + package io.optimism.spec.derive.stages; + + import io.optimism.spec.derive.types.L2BlockRef; + import io.optimism.spec.derive.types.OpPayloadAttributes; + import io.optimism.spec.derive.types.Epoch; + + public interface AttributesBuilder { + + OpPayloadAttributes preparePayloadAttr(L2BlockRef ref, Epoch epoch); + + } diff --git a/src/main/java/io/optimism/spec/derive/stages/AttributesProvider.java b/src/main/java/io/optimism/spec/derive/stages/AttributesProvider.java new file mode 100644 index 00000000..d5fff8d5 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/stages/AttributesProvider.java @@ -0,0 +1,19 @@ +package io.optimism.spec.derive.stages; + +import io.optimism.types.L2BlockRef; +import io.optimism.types.SingularBatch; + +public interface AttributesProvider { + /** + * returns the next valid batch upon the given safe head. + * @param parent + * @return + */ + SingularBatch nextBatch(L2BlockRef parent); + + /** + * + * @return + */ + boolean isLastInSpan(); +} diff --git a/src/main/java/io/optimism/spec/derive/stages/BatchQueueProvider.java b/src/main/java/io/optimism/spec/derive/stages/BatchQueueProvider.java new file mode 100644 index 00000000..f6d865a4 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/stages/BatchQueueProvider.java @@ -0,0 +1,11 @@ +package io.optimism.spec.derive.stages; + +import io.optimism.spec.derive.types.Batch; + +public interface BatchQueueProvider { + + Batch nextBatch(); + + void flush(); + +} diff --git a/src/main/java/io/optimism/spec/derive/stages/ChannelBankProvider.java b/src/main/java/io/optimism/spec/derive/stages/ChannelBankProvider.java new file mode 100644 index 00000000..8beef502 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/stages/ChannelBankProvider.java @@ -0,0 +1,9 @@ +package io.optimism.spec.derive.stages; + +import io.optimism.spec.derive.types.Frame; + +public interface ChannelBankProvider { + + Frame nextFrame(); + +} diff --git a/src/main/java/io/optimism/spec/derive/stages/ChannelReaderProvider.java b/src/main/java/io/optimism/spec/derive/stages/ChannelReaderProvider.java new file mode 100644 index 00000000..d0cf5a6b --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/stages/ChannelReaderProvider.java @@ -0,0 +1,7 @@ +package io.optimism.spec.derive.stages; + +public interface ChannelReaderProvider { + + byte[] nextData(); + +} diff --git a/src/main/java/io/optimism/spec/derive/stages/DataIter.java b/src/main/java/io/optimism/spec/derive/stages/DataIter.java new file mode 100644 index 00000000..2b705eb7 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/stages/DataIter.java @@ -0,0 +1,7 @@ +package io.optimism.spec.derive.stages; + +public interface DataIter { + + byte[] Next(); + +} diff --git a/src/main/java/io/optimism/spec/derive/stages/FrameQueueProvider.java b/src/main/java/io/optimism/spec/derive/stages/FrameQueueProvider.java new file mode 100644 index 00000000..4cbd3260 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/stages/FrameQueueProvider.java @@ -0,0 +1,5 @@ +package io.optimism.spec.derive.stages; + +public interface FrameQueueProvider { + byte[] next(); +} diff --git a/src/main/java/io/optimism/spec/derive/stages/L1RetrievalProvider.java b/src/main/java/io/optimism/spec/derive/stages/L1RetrievalProvider.java new file mode 100644 index 00000000..a43a0588 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/stages/L1RetrievalProvider.java @@ -0,0 +1,11 @@ +package io.optimism.spec.derive.stages; + +import io.optimism.types.BlockInfo; + +public interface L1RetrievalProvider { + + BlockInfo nextL1Block(); + + String batcherAddr(); + +} diff --git a/src/main/java/io/optimism/spec/derive/stages/NextAttributes.java b/src/main/java/io/optimism/spec/derive/stages/NextAttributes.java new file mode 100644 index 00000000..dcb34079 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/stages/NextAttributes.java @@ -0,0 +1,10 @@ +package io.optimism.spec.derive.stages; + +import io.optimism.spec.derive.types.L2BlockRef; +import io.optimism.spec.derive.types.OpAttributesWithParent; + +public interface NextAttributes { + + OpAttributesWithParent nextAttr(L2BlockRef parent); + +} diff --git a/src/main/java/io/optimism/spec/derive/stages/OriginAdvancer.java b/src/main/java/io/optimism/spec/derive/stages/OriginAdvancer.java new file mode 100644 index 00000000..fa0094e3 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/stages/OriginAdvancer.java @@ -0,0 +1,5 @@ +package io.optimism.spec.derive.stages; + +public interface OriginAdvancer { + void advanceOrigin(); +} diff --git a/src/main/java/io/optimism/spec/derive/stages/OriginProvider.java b/src/main/java/io/optimism/spec/derive/stages/OriginProvider.java new file mode 100644 index 00000000..96689223 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/stages/OriginProvider.java @@ -0,0 +1,8 @@ +package io.optimism.spec.derive.stages; + +import io.optimism.types.BlockInfo; + +public interface OriginProvider { + + BlockInfo origin(); +} diff --git a/src/main/java/io/optimism/spec/derive/stages/ResettableStage.java b/src/main/java/io/optimism/spec/derive/stages/ResettableStage.java new file mode 100644 index 00000000..828001f6 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/stages/ResettableStage.java @@ -0,0 +1,9 @@ +package io.optimism.spec.derive.stages; + +import io.optimism.config.Config; +import io.optimism.types.BlockInfo; + +public interface ResettableStage { + + void reset(BlockInfo base, Config.SystemConfig config); +} diff --git a/src/main/java/io/optimism/spec/derive/stages/impl/AttributesQueue.java b/src/main/java/io/optimism/spec/derive/stages/impl/AttributesQueue.java new file mode 100644 index 00000000..ef554719 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/stages/impl/AttributesQueue.java @@ -0,0 +1,40 @@ +package io.optimism.spec.derive.stages.impl; + +import io.optimism.config.Config; +import io.optimism.spec.derive.stages.AttributesBuilder; +import io.optimism.spec.derive.stages.NextAttributes; +import io.optimism.spec.derive.stages.OriginAdvancer; +import io.optimism.spec.derive.stages.OriginProvider; +import io.optimism.spec.derive.stages.ResettableStage; +import io.optimism.spec.derive.types.Epoch; +import io.optimism.spec.derive.types.L2BlockRef; +import io.optimism.spec.derive.types.OpAttributesWithParent; +import io.optimism.spec.derive.types.OpPayloadAttributes; +import io.optimism.types.BlockInfo; + +public class AttributesQueue implements NextAttributes, OriginAdvancer, OriginProvider, ResettableStage, AttributesBuilder { + @Override + public OpPayloadAttributes preparePayloadAttr(L2BlockRef ref, Epoch epoch) { + return null; + } + + @Override + public void advanceOrigin() { + + } + + @Override + public BlockInfo origin() { + return null; + } + + @Override + public void reset(BlockInfo base, Config.SystemConfig config) { + + } + + @Override + public OpAttributesWithParent nextAttr(L2BlockRef parent) { + return null; + } +} diff --git a/src/main/java/io/optimism/spec/derive/stages/impl/BatchQueue.java b/src/main/java/io/optimism/spec/derive/stages/impl/BatchQueue.java new file mode 100644 index 00000000..2f85555e --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/stages/impl/BatchQueue.java @@ -0,0 +1,37 @@ +package io.optimism.spec.derive.stages.impl; + +import io.optimism.config.Config; +import io.optimism.spec.derive.stages.AttributesProvider; +import io.optimism.spec.derive.stages.OriginAdvancer; +import io.optimism.spec.derive.stages.OriginProvider; +import io.optimism.spec.derive.stages.ResettableStage; +import io.optimism.types.BlockInfo; +import io.optimism.types.L2BlockRef; +import io.optimism.types.SingularBatch; + +public class BatchQueue implements AttributesProvider, OriginProvider, OriginAdvancer, ResettableStage { + @Override + public SingularBatch nextBatch(L2BlockRef parent) { + return null; + } + + @Override + public boolean isLastInSpan() { + return false; + } + + @Override + public void advanceOrigin() { + + } + + @Override + public BlockInfo origin() { + return null; + } + + @Override + public void reset(BlockInfo base, Config.SystemConfig config) { + + } +} diff --git a/src/main/java/io/optimism/spec/derive/stages/impl/BatchStream.java b/src/main/java/io/optimism/spec/derive/stages/impl/BatchStream.java new file mode 100644 index 00000000..21fa371d --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/stages/impl/BatchStream.java @@ -0,0 +1,36 @@ +package io.optimism.spec.derive.stages.impl; + +import io.optimism.config.Config; +import io.optimism.spec.derive.stages.BatchQueueProvider; +import io.optimism.spec.derive.stages.OriginAdvancer; +import io.optimism.spec.derive.stages.OriginProvider; +import io.optimism.spec.derive.stages.ResettableStage; +import io.optimism.spec.derive.types.Batch; +import io.optimism.types.BlockInfo; + +public class BatchStream implements BatchQueueProvider, OriginProvider, OriginAdvancer, ResettableStage { + @Override + public Batch nextBatch() { + return null; + } + + @Override + public void flush() { + + } + + @Override + public void advanceOrigin() { + + } + + @Override + public BlockInfo origin() { + return null; + } + + @Override + public void reset(BlockInfo base, Config.SystemConfig config) { + + } +} diff --git a/src/main/java/io/optimism/spec/derive/stages/impl/ChannelBank.java b/src/main/java/io/optimism/spec/derive/stages/impl/ChannelBank.java new file mode 100644 index 00000000..9762749c --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/stages/impl/ChannelBank.java @@ -0,0 +1,30 @@ +package io.optimism.spec.derive.stages.impl; + +import io.optimism.config.Config; +import io.optimism.spec.derive.stages.ChannelReaderProvider; +import io.optimism.spec.derive.stages.OriginAdvancer; +import io.optimism.spec.derive.stages.OriginProvider; +import io.optimism.spec.derive.stages.ResettableStage; +import io.optimism.types.BlockInfo; + +public class ChannelBank implements ChannelReaderProvider, OriginProvider, OriginAdvancer, ResettableStage { + @Override + public byte[] nextData() { + return new byte[0]; + } + + @Override + public void advanceOrigin() { + + } + + @Override + public BlockInfo origin() { + return null; + } + + @Override + public void reset(BlockInfo base, Config.SystemConfig config) { + + } +} diff --git a/src/main/java/io/optimism/spec/derive/stages/impl/ChannelReader.java b/src/main/java/io/optimism/spec/derive/stages/impl/ChannelReader.java new file mode 100644 index 00000000..dafa4144 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/stages/impl/ChannelReader.java @@ -0,0 +1,36 @@ +package io.optimism.spec.derive.stages.impl; + +import io.optimism.config.Config; +import io.optimism.spec.derive.stages.BatchQueueProvider; +import io.optimism.spec.derive.stages.OriginAdvancer; +import io.optimism.spec.derive.stages.OriginProvider; +import io.optimism.spec.derive.stages.ResettableStage; +import io.optimism.spec.derive.types.Batch; +import io.optimism.types.BlockInfo; + +public class ChannelReader implements BatchQueueProvider, OriginProvider, OriginAdvancer, ResettableStage { + @Override + public Batch nextBatch() { + return null; + } + + @Override + public void flush() { + + } + + @Override + public void advanceOrigin() { + + } + + @Override + public BlockInfo origin() { + return null; + } + + @Override + public void reset(BlockInfo base, Config.SystemConfig config) { + + } +} diff --git a/src/main/java/io/optimism/spec/derive/stages/impl/FrameQueue.java b/src/main/java/io/optimism/spec/derive/stages/impl/FrameQueue.java new file mode 100644 index 00000000..b1eb3656 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/stages/impl/FrameQueue.java @@ -0,0 +1,32 @@ +package io.optimism.spec.derive.stages.impl; + +import io.optimism.config.Config; +import io.optimism.spec.derive.stages.ChannelBankProvider; +import io.optimism.spec.derive.stages.OriginAdvancer; +import io.optimism.spec.derive.stages.OriginProvider; +import io.optimism.spec.derive.stages.ResettableStage; +import io.optimism.spec.derive.types.Frame; +import io.optimism.types.BlockInfo; + +public class FrameQueue implements ChannelBankProvider, OriginProvider, OriginAdvancer, ResettableStage { + + @Override + public Frame nextFrame() { + return null; + } + + @Override + public void advanceOrigin() { + + } + + @Override + public BlockInfo origin() { + return null; + } + + @Override + public void reset(BlockInfo base, Config.SystemConfig config) { + + } +} diff --git a/src/main/java/io/optimism/spec/derive/types/Batch.java b/src/main/java/io/optimism/spec/derive/types/Batch.java new file mode 100644 index 00000000..4ad98b30 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/types/Batch.java @@ -0,0 +1,18 @@ +package io.optimism.spec.derive.types; + +import io.optimism.spec.derive.types.enums.BatchType; + +import java.math.BigInteger; + +public interface Batch { + + BatchType type(); + + BigInteger getTimestamp(); + + byte[] encode(); + + + + +} diff --git a/src/main/java/io/optimism/spec/derive/types/BatchWithInclusionBlock.java b/src/main/java/io/optimism/spec/derive/types/BatchWithInclusionBlock.java new file mode 100644 index 00000000..508aadf5 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/types/BatchWithInclusionBlock.java @@ -0,0 +1,4 @@ +package io.optimism.spec.derive.types; + +public class BatchWithInclusionBlock { +} diff --git a/src/main/java/io/optimism/spec/derive/types/BlobSidecar.java b/src/main/java/io/optimism/spec/derive/types/BlobSidecar.java new file mode 100644 index 00000000..71d549e5 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/types/BlobSidecar.java @@ -0,0 +1,200 @@ +package io.optimism.spec.derive.types; + +import com.fasterxml.jackson.annotation.JsonAlias; +import io.optimism.types.BeaconSignedBlockHeader; +import org.web3j.crypto.Hash; +import org.web3j.utils.Numeric; + +import java.util.List; +import java.util.Objects; + +/** + * The BlobSidecar class + * + * @author thinkAfCod + * @since 0.3.0 + */ +public class BlobSidecar { + private String index; + private String blob; + + @JsonAlias("signed_block_header") + private BeaconSignedBlockHeader signedBlockHeader; + + @JsonAlias("kzg_commitment") + private String kzgCommitment; + + @JsonAlias("kzg_proof") + private String kzgProof; + + @JsonAlias("kzg_commitment_inclusion_proof") + private List kzgCommitmentInclusionProof; + + /** + * The BlobSidecar constructor. + */ + public BlobSidecar() {} + + /** + * The BlobSidecar constructor. + * + * @param index the blob index + * @param blob the blob data + * @param signedBlockHeader signed blob block header info + * @param kzgCommitment the kzg commitment info + * @param kzgProof the kzg proofs + * @param kzgCommitmentInclusionProof the kzg commitment inclusion proofs + */ + public BlobSidecar( + String index, + String blob, + BeaconSignedBlockHeader signedBlockHeader, + String kzgCommitment, + String kzgProof, + List kzgCommitmentInclusionProof) { + this.index = index; + this.blob = blob; + this.signedBlockHeader = signedBlockHeader; + this.kzgCommitment = kzgCommitment; + this.kzgProof = kzgProof; + this.kzgCommitmentInclusionProof = kzgCommitmentInclusionProof; + } + + /** + * Gets index. + * + * @return the index + */ + public String getIndex() { + return index; + } + + /** + * Sets index value. + * + * @param index the index + */ + public void setIndex(String index) { + this.index = index; + } + + /** + * Gets blob. + * + * @return the blob + */ + public String getBlob() { + return blob; + } + + /** + * Sets blob value. + * + * @param blob the blob + */ + public void setBlob(String blob) { + this.blob = blob; + } + + /** + * Gets signed block header. + * + * @return the signed block header + */ + public BeaconSignedBlockHeader getSignedBlockHeader() { + return signedBlockHeader; + } + + /** + * Sets signed block header value. + * + * @param signedBlockHeader the signed block header + */ + public void setSignedBlockHeader(BeaconSignedBlockHeader signedBlockHeader) { + this.signedBlockHeader = signedBlockHeader; + } + + /** + * Gets kzg commitment. + * + * @return the kzg commitment + */ + public String getKzgCommitment() { + return kzgCommitment; + } + + /** + * Sets kzg commitment value. + * + * @param kzgCommitment the kzg commitment + */ + public void setKzgCommitment(String kzgCommitment) { + this.kzgCommitment = kzgCommitment; + } + + /** + * Gets kzg proof. + * + * @return the kzg proof + */ + public String getKzgProof() { + return kzgProof; + } + + /** + * Sets kzg proof value. + * + * @param kzgProof the kzg proof + */ + public void setKzgProof(String kzgProof) { + this.kzgProof = kzgProof; + } + + /** + * Gets kzg commitment inclusion proof. + * + * @return the kzg commitment inclusion proof + */ + public List getKzgCommitmentInclusionProof() { + return kzgCommitmentInclusionProof; + } + + /** + * Sets kzg commitment inclusion proof value. + * + * @param kzgCommitmentInclusionProof the kzg commitment inclusion proof + */ + public void setKzgCommitmentInclusionProof(List kzgCommitmentInclusionProof) { + this.kzgCommitmentInclusionProof = kzgCommitmentInclusionProof; + } + + /** + * Gets versioned hash. + * + * @return the versioned hash + */ + public String getVersionedHash() { + var hash = Hash.sha256(Numeric.hexStringToByteArray(this.kzgCommitment)); + hash[0] = 1; + return Numeric.toHexString(hash); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof BlobSidecar that)) { + return false; + } + return Objects.equals(index, that.index) + && Objects.equals(blob, that.blob) + && Objects.equals(signedBlockHeader, that.signedBlockHeader) + && Objects.equals(kzgCommitment, that.kzgCommitment) + && Objects.equals(kzgProof, that.kzgProof) + && Objects.equals(kzgCommitmentInclusionProof, that.kzgCommitmentInclusionProof); + } + + @Override + public int hashCode() { + return Objects.hash(index, blob, signedBlockHeader, kzgCommitment, kzgProof, kzgCommitmentInclusionProof); + } +} diff --git a/src/main/java/io/optimism/spec/derive/types/Epoch.java b/src/main/java/io/optimism/spec/derive/types/Epoch.java new file mode 100644 index 00000000..1606265a --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/types/Epoch.java @@ -0,0 +1,39 @@ +package io.optimism.spec.derive.types; + +import io.optimism.types.L1BlockInfo; + +import java.math.BigInteger; + +/** + * The type Epoch. + * + * @param number L1 block number. + * @param hash L1 block hash. + * @param timestamp L1 block timestamp. + * @param sequenceNumber The sequence number of the batcher transactions. + * @author grapebaba + * @since 0.1.0 + */ +public record Epoch(BigInteger number, String hash, BigInteger timestamp, BigInteger sequenceNumber) { + + /** + * Create epoch from L1BlockInfo. + * + * @param info the L1 block info + * @return the epoch + */ + public static Epoch from(L1BlockInfo info) { + return new Epoch(info.number(), info.blockHash(), info.time(), info.sequenceNumber()); + } + + /** + * Creates epoch from an another epoch and sets sequence number. + * + * @param epoch the epoch info + * @param sequenceNumber the sequence number + * @return a new epoch with sequence number + */ + public static Epoch from(Epoch epoch, BigInteger sequenceNumber) { + return new Epoch(epoch.number(), epoch.hash(), epoch.timestamp(), sequenceNumber); + } +} diff --git a/src/main/java/io/optimism/spec/derive/types/Frame.java b/src/main/java/io/optimism/spec/derive/types/Frame.java new file mode 100644 index 00000000..3bf82ff3 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/types/Frame.java @@ -0,0 +1,124 @@ +package io.optimism.spec.derive.types; + +import com.google.common.base.Objects; +import com.google.common.primitives.Ints; +import com.google.common.primitives.Shorts; +import io.optimism.exceptions.InvalidFrameSizeException; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.web3j.utils.Numeric; + +import java.io.ByteArrayOutputStream; +import java.math.BigInteger; + +/** + * The type Frame. + * + * @param channelId the channel id + * @param frameNumber the frame number + * @param frameDataLen the frame data len + * @param frameData the frame data + * @param isLastFrame the is last frame + * @author grapebaba + * @since 0.1.0 + */ +public record Frame( + BigInteger channelId, + Integer frameNumber, + Integer frameDataLen, + byte[] frameData, + Boolean isLastFrame) { + + private static final Logger LOGGER = LoggerFactory.getLogger(Frame.class); + + /** Derivation version. */ + public static final byte DERIVATION_VERSION_0 = 0; + + /** + * Frame over head size. + */ + public static final int FRAME_V0_OVER_HEAD_SIZE = 23; + + /** + * Get tx bytes. + * + * @return tx bytes + */ + public byte[] txBytes() { + return ArrayUtils.addAll(new byte[] {DERIVATION_VERSION_0}, frameData()); + } + + /** + * Get Tx data unique code. + * + * @return unique code. + */ + public String code() { + return String.valueOf(Objects.hashCode(channelId, frameNumber)); + } + + /** + * Create a new Frame instance. + * + * @param chId channel id + * @param frameNumber frame number + * @param data frame data + * @param isLastFrame is last frame + * @return a new Frame instance + */ + public static Frame create(BigInteger chId, int frameNumber, byte[] data, boolean isLastFrame) { + var dataLen = data == null ? 0 : data.length; + return new Frame(chId, frameNumber, dataLen, data, isLastFrame); + } + + /** + * Encode this Frame to bytes. + * + * @return encoded bytes from frame + */ + public byte[] encode() { + var bos = new ByteArrayOutputStream(); + bos.writeBytes(Numeric.toBytesPadded(channelId, 16)); + bos.writeBytes(Shorts.toByteArray((short) frameNumber().intValue())); + bos.writeBytes(Ints.toByteArray(frameData().length)); + bos.writeBytes(frameData()); + bos.write(isLastFrame() ? 1 : 0); + return bos.toByteArray(); + } + + /** + * From data immutable pair. + * + * @param data the data + * @param offset the offset + * @param l1InclusionBlock the L1 inclusion block + * @return the immutable pair + */ + public static ImmutablePair from(byte[] data, int offset, BigInteger l1InclusionBlock) { + final byte[] frameDataMessage = ArrayUtils.subarray(data, offset, data.length); + if (frameDataMessage.length < 23) { + throw new InvalidFrameSizeException("invalid frame size"); + } + + final BigInteger channelId = Numeric.toBigInt(ArrayUtils.subarray(frameDataMessage, 0, 16)); + final int frameNumber = + Numeric.toBigInt(ArrayUtils.subarray(frameDataMessage, 16, 18)).intValue(); + final int frameDataLen = + Numeric.toBigInt(ArrayUtils.subarray(frameDataMessage, 18, 22)).intValue(); + final int frameDataEnd = 22 + frameDataLen; + + if (frameDataMessage.length < frameDataEnd) { + throw new InvalidFrameSizeException("invalid frame size"); + } + + final byte[] frameData = ArrayUtils.subarray(frameDataMessage, 22, frameDataEnd); + final boolean isLastFrame = frameDataMessage[frameDataEnd] != 0; + final Frame frame = new Frame(channelId, frameNumber, frameDataLen, frameData, isLastFrame, l1InclusionBlock); + LOGGER.debug(String.format( + "saw batcher tx: block=%d, number=%d, is_last=%b", l1InclusionBlock, frameNumber, isLastFrame)); + + return new ImmutablePair<>(frame, offset + frameDataMessage.length); + } +} diff --git a/src/main/java/io/optimism/spec/derive/types/L2BlockRef.java b/src/main/java/io/optimism/spec/derive/types/L2BlockRef.java new file mode 100644 index 00000000..0d37802e --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/types/L2BlockRef.java @@ -0,0 +1,86 @@ +package io.optimism.spec.derive.types; + +import io.optimism.types.BlockId; +import io.optimism.types.Epoch; +import io.optimism.types.L1BlockInfo; +import org.web3j.protocol.core.methods.response.EthBlock; + +import java.math.BigInteger; +import java.util.Objects; + +/** + * L2 block brief information. + * + * @param hash L1 block hash + * @param number L1 block number + * @param parentHash L1 block parent hash + * @param timestamp L1 Block timestamp + * @param l1origin L1 blockId information + * @param sequenceNumber sequence number that distance to first block of epoch + * @author thinkAfCod + * @since 0.1.1 + */ +public record L2BlockRef( + String hash, + BigInteger number, + String parentHash, + BigInteger timestamp, + Epoch l1origin, + BigInteger sequenceNumber) { + + public static final L2BlockRef EMPTY = new L2BlockRef(null, null, null, null, null, null); + + /** + * L2BlockRef instance converts to BlockId instance. + * + * @return BlockId instance + */ + public BlockId toId() { + return new BlockId(hash, number); + } + + /** + * Create a L2BlockRef instance from EthBlock.Block and L1BlockInfo + * + * @param block block info + * @param l1Info l1 block info + * @return L2BlockRef instance + */ + public static L2BlockRef fromBlockAndL1Info(EthBlock.Block block, L1BlockInfo l1Info) { + return new L2BlockRef( + block.getHash(), + block.getNumber(), + block.getParentHash(), + block.getTimestamp(), + l1Info.toEpoch(), + l1Info.sequenceNumber()); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof L2BlockRef that)) return false; + return Objects.equals(hash, that.hash) + && Objects.equals(number, that.number) + && Objects.equals(parentHash, that.parentHash) + && Objects.equals(timestamp, that.timestamp) + && Objects.equals(l1origin, that.l1origin) + && Objects.equals(sequenceNumber, that.sequenceNumber); + } + + @Override + public int hashCode() { + return Objects.hash(hash, number, parentHash, timestamp, l1origin, sequenceNumber); + } + + @Override + public String toString() { + return "L2BlockRef{" + "hash='" + + hash + '\'' + ", number=" + + number + ", parentHash='" + + parentHash + '\'' + ", timestamp=" + + timestamp + ", l1origin=" + + l1origin + ", sequenceNumber=" + + sequenceNumber + '}'; + } +} diff --git a/src/main/java/io/optimism/spec/derive/types/OpAttributesWithParent.java b/src/main/java/io/optimism/spec/derive/types/OpAttributesWithParent.java new file mode 100644 index 00000000..c20359f6 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/types/OpAttributesWithParent.java @@ -0,0 +1,6 @@ +package io.optimism.spec.derive.types; + +public record OpAttributesWithParent( + OpPayloadAttributes attributes, + L2BlockRef parent, + Boolean isLastInSpan) {} diff --git a/src/main/java/io/optimism/spec/derive/types/OpPayloadAttributes.java b/src/main/java/io/optimism/spec/derive/types/OpPayloadAttributes.java new file mode 100644 index 00000000..68af5dab --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/types/OpPayloadAttributes.java @@ -0,0 +1,21 @@ +package io.optimism.spec.derive.types; + +import io.optimism.types.Epoch; +import org.web3j.protocol.core.methods.response.EthBlock; + +import java.math.BigInteger; +import java.util.List; + +public record OpPayloadAttributes( + BigInteger timestamp, + String prevRandao, + String suggestedFeeRecipient, + List transactions, + List withdrawals, + boolean noTxPool, + BigInteger gasLimit, + Epoch epoch, + BigInteger l1InclusionBlock, + BigInteger seqNumber, + String parentBeaconBlockRoot) {} + diff --git a/src/main/java/io/optimism/spec/derive/types/SingularBatch.java b/src/main/java/io/optimism/spec/derive/types/SingularBatch.java new file mode 100644 index 00000000..daad8973 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/types/SingularBatch.java @@ -0,0 +1,22 @@ +package io.optimism.spec.derive.types; + +import io.optimism.spec.derive.types.enums.BatchType; + +import java.math.BigInteger; + +public class SingularBatch implements Batch{ + @Override + public BatchType type() { + return null; + } + + @Override + public BigInteger getTimestamp() { + return null; + } + + @Override + public byte[] encode() { + return new byte[0]; + } +} diff --git a/src/main/java/io/optimism/spec/derive/types/SpanBatch.java b/src/main/java/io/optimism/spec/derive/types/SpanBatch.java new file mode 100644 index 00000000..611f42bf --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/types/SpanBatch.java @@ -0,0 +1,22 @@ +package io.optimism.spec.derive.types; + +import io.optimism.spec.derive.types.enums.BatchType; + +import java.math.BigInteger; + +public class SpanBatch implements Batch{ + @Override + public BatchType type() { + return null; + } + + @Override + public BigInteger getTimestamp() { + return null; + } + + @Override + public byte[] encode() { + return new byte[0]; + } +} diff --git a/src/main/java/io/optimism/spec/derive/types/enums/BatchType.java b/src/main/java/io/optimism/spec/derive/types/enums/BatchType.java new file mode 100644 index 00000000..39f619e1 --- /dev/null +++ b/src/main/java/io/optimism/spec/derive/types/enums/BatchType.java @@ -0,0 +1,58 @@ +package io.optimism.spec.derive.types.enums; + +/** + * The enum Batch type. + * + * @author grapebaba + * @since 0.2.4 + */ +public enum BatchType { + /** + * Singular batch type batch type. + */ + SINGULAR_BATCH_TYPE(0, "SingularBatchType"), + /** + * Span batch type batch type. + */ + SPAN_BATCH_TYPE(1, "SpanBatchType"); + private final int code; + private final String name; + + BatchType(int code, String name) { + this.code = code; + this.name = name; + } + + /** + * Gets code. + * + * @return the code + */ + public int getCode() { + return code; + } + + /** + * Gets name. + * + * @return the name + */ + public String getName() { + return name; + } + + /** + * From batch type. + * + * @param code the code + * @return the batch type + */ + public static BatchType from(int code) { + for (BatchType batchType : BatchType.values()) { + if (batchType.getCode() == code) { + return batchType; + } + } + throw new IllegalArgumentException("Invalid BatchType code: %d".formatted(code)); + } +} diff --git a/src/main/java/io/optimism/types/enums/BatchStatus.java b/src/main/java/io/optimism/types/enums/BatchStatus.java new file mode 100644 index 00000000..66f4032f --- /dev/null +++ b/src/main/java/io/optimism/types/enums/BatchStatus.java @@ -0,0 +1,12 @@ +package io.optimism.types.enums; + +public enum BatchStatus { + /** Drop batch status. */ + Drop, + /** Accept batch status. */ + Accept, + /** Undecided batch status. */ + Undecided, + /** Future batch status. */ + Future, +} diff --git a/src/main/java/io/optimism/utilities/LruCacheProvider.java b/src/main/java/io/optimism/utilities/LruCacheProvider.java new file mode 100644 index 00000000..5c338d0c --- /dev/null +++ b/src/main/java/io/optimism/utilities/LruCacheProvider.java @@ -0,0 +1,14 @@ +package io.optimism.utilities; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; + +public class LruCacheProvider { + + static Cache create() { + return CacheBuilder.newBuilder() + .maximumSize(1000L) + .build(); + } + +}