Skip to content
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

activation span batch feature #98

Merged
merged 11 commits into from
Jan 31, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import io.optimism.batcher.telemetry.BatcherMetrics;
import io.optimism.type.BlockId;
import io.optimism.type.L1BlockInfo;
import io.optimism.utilities.derive.stages.Batch;
import io.optimism.utilities.derive.stages.Frame;
import io.optimism.utilities.derive.stages.SingularBatch;
import java.io.IOException;
import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
Expand Down Expand Up @@ -106,9 +106,9 @@ public L1BlockInfo addBlock(final EthBlock.Block block) {
if (this.isClose) {
throw new ChannelException("channel already closed");
}
final Tuple2<L1BlockInfo, Batch> l1InfoAndBatch = this.blockToBatch(block);
final Tuple2<L1BlockInfo, SingularBatch> l1InfoAndBatch = this.blockToBatch(block);
final L1BlockInfo l1Info = l1InfoAndBatch.component1();
final Batch batch = l1InfoAndBatch.component2();
final SingularBatch batch = l1InfoAndBatch.component2();
try {
this.addBatch(batch);
this.blocks.add(block);
Expand Down Expand Up @@ -286,7 +286,7 @@ public void close() {
}

@SuppressWarnings({"rawtypes", "unchecked"})
private Tuple2<L1BlockInfo, Batch> blockToBatch(EthBlock.Block block) {
private Tuple2<L1BlockInfo, SingularBatch> blockToBatch(EthBlock.Block block) {
final List<EthBlock.TransactionResult> blockTxs = block.getTransactions();
if (blockTxs == null || blockTxs.isEmpty()) {
throw new ChannelException(String.format("block %s has no transations", block.getHash()));
Expand All @@ -308,16 +308,11 @@ private Tuple2<L1BlockInfo, Batch> blockToBatch(EthBlock.Block block) {
}
return new Tuple2(
l1Info,
new Batch(
block.getParentHash(),
l1Info.number(),
l1Info.blockHash(),
block.getTimestamp(),
txDataList,
null));
new SingularBatch(
block.getParentHash(), l1Info.number(), l1Info.blockHash(), block.getTimestamp(), txDataList));
}

private int addBatch(Batch batch) {
private int addBatch(SingularBatch batch) {
if (this.isClose) {
throw new ChannelException("channel already closed");
}
Expand Down Expand Up @@ -385,7 +380,7 @@ private Frame frame(final int maxSize) {
return frame;
}

private void updateSeqWindowTimeout(final Batch batch) {
private void updateSeqWindowTimeout(final SingularBatch batch) {
var timeout = batch.epochNum().add(this.seqWindowTimeout);
this.updateTimeout(timeout);
}
Expand Down
18 changes: 16 additions & 2 deletions hildr-node/src/main/java/io/optimism/config/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static java.util.Map.entry;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
Expand Down Expand Up @@ -180,6 +181,8 @@ public Map<String, String> toConfigMap() {
* The type ChainConfig.
*
* @param network The network name.
* @param l1ChainId The L1 chain id.
* @param l2ChainId The L2 chain id.
* @param l1StartEpoch The L1 block referenced by the L2 chainConfig.
* @param l2Genesis The L2 genesis block info.
* @param systemConfig The initial system config value.
Expand All @@ -192,10 +195,9 @@ public Map<String, String> toConfigMap() {
* @param maxSeqDrift Maximum timestamp drift.
* @param regolithTime Timestamp of the regolith hardfork.
* @param canyonTime Timestamp of the canyon hardfork.
* @param deltaTime Timestamp of the canyon hardfork.
* @param blockTime Network blocktime.
* @param l2Tol1MessagePasser L2 To L1 Message passer address.
* @param l1ChainId The L1 chain id.
* @param l2ChainId The L2 chain id.
* @author grapebaba
* @since 0.1.0
*/
Expand All @@ -215,6 +217,7 @@ public record ChainConfig(
BigInteger maxSeqDrift,
BigInteger regolithTime,
BigInteger canyonTime,
BigInteger deltaTime,
BigInteger blockTime,
String l2Tol1MessagePasser) {

Expand Down Expand Up @@ -252,6 +255,7 @@ public static ChainConfig optimism() {
BigInteger.valueOf(600L),
BigInteger.ZERO,
BigInteger.valueOf(1704992401L),
BigInteger.valueOf(-1L),
BigInteger.valueOf(2L),
"0x4200000000000000000000000000000000000016");
}
Expand Down Expand Up @@ -290,6 +294,7 @@ public static ChainConfig base() {
BigInteger.valueOf(600L),
BigInteger.ZERO,
BigInteger.valueOf(1704992401L),
BigInteger.valueOf(-1L),
BigInteger.valueOf(2L),
"0x4200000000000000000000000000000000000016");
}
Expand Down Expand Up @@ -328,6 +333,7 @@ public static ChainConfig optimismGoerli() {
BigInteger.valueOf(600L),
BigInteger.valueOf(1679079600L),
BigInteger.valueOf(1699981200L),
BigInteger.valueOf(1703116800L),
BigInteger.valueOf(2L),
"0xEF2ec5A5465f075E010BE70966a8667c94BCe15a");
}
Expand Down Expand Up @@ -366,6 +372,7 @@ public static ChainConfig optimismSepolia() {
BigInteger.valueOf(600L),
BigInteger.ZERO,
BigInteger.valueOf(1699981200L),
BigInteger.valueOf(1703203200L),
BigInteger.valueOf(2L),
"0x4200000000000000000000000000000000000016");
}
Expand Down Expand Up @@ -404,6 +411,7 @@ public static ChainConfig baseGoerli() {
BigInteger.valueOf(600L),
BigInteger.valueOf(1683219600L),
BigInteger.valueOf(1699981200L),
BigInteger.valueOf(-1L),
BigInteger.valueOf(2L),
"0x4200000000000000000000000000000000000016");
}
Expand Down Expand Up @@ -442,6 +450,7 @@ public static ChainConfig baseSepolia() {
BigInteger.valueOf(600L),
BigInteger.ZERO,
BigInteger.valueOf(1699981200L),
BigInteger.valueOf(-1L),
BigInteger.valueOf(2L),
"0x4200000000000000000000000000000000000016");
}
Expand All @@ -454,6 +463,7 @@ public static ChainConfig baseSepolia() {
*/
public static ChainConfig fromJson(String filePath) {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
ExternalChainConfig externalChainConfig = mapper.readValue(
Files.readString(Path.of(filePath), StandardCharsets.UTF_8), ExternalChainConfig.class);
Expand Down Expand Up @@ -495,6 +505,7 @@ public static ChainConfig fromExternal(ExternalChainConfig external) {
external.maxSequencerDrift,
external.regolithTime,
external.canyonTime == null ? BigInteger.valueOf(-1L) : external.canyonTime,
external.deltaTime == null ? BigInteger.valueOf(-1L) : external.deltaTime,
external.blockTime,
"0x4200000000000000000000000000000000000016");
}
Expand Down Expand Up @@ -544,6 +555,7 @@ public Map<String, String> toConfigMap() {
entry("config.chainConfig.maxSeqDrift", this.maxSeqDrift.toString()),
entry("config.chainConfig.regolithTime", this.regolithTime.toString()),
entry("config.chainConfig.canyonTime", this.canyonTime.toString()),
entry("config.chainConfig.deltaTime", this.deltaTime.toString()),
entry("config.chainConfig.blockTime", this.blockTime.toString()),
entry("config.chainConfig.l2Tol1MessagePasser", this.l2Tol1MessagePasser));
}
Expand Down Expand Up @@ -657,6 +669,7 @@ public String batcherHash() {
* @param l2ChainId l2 chain id
* @param regolithTime regolith time
* @param canyonTime canyon time
* @param deltaTime delta time
* @param batchInboxAddress batch inbox address
* @param depositContractAddress deposit contract address
* @param l1SystemConfigAddress l1 system config address
Expand All @@ -673,6 +686,7 @@ public record ExternalChainConfig(
BigInteger l2ChainId,
BigInteger regolithTime,
BigInteger canyonTime,
BigInteger deltaTime,
String batchInboxAddress,
String depositContractAddress,
String l1SystemConfigAddress) {}
Expand Down
96 changes: 94 additions & 2 deletions hildr-node/src/main/java/io/optimism/derive/State.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@
import io.optimism.common.BlockInfo;
import io.optimism.common.Epoch;
import io.optimism.config.Config;
import io.optimism.driver.HeadInfo;
import io.optimism.l1.L1Info;
import java.math.BigInteger;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.StructuredTaskScope;
import org.apache.commons.lang3.StringUtils;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameter;
import org.web3j.protocol.core.methods.response.EthBlock;
import org.web3j.tuples.generated.Tuple2;

/**
* The type State.
Expand All @@ -21,6 +28,8 @@ public class State {

private final TreeMap<BigInteger, String> l1Hashes;

private final TreeMap<BigInteger, Tuple2<BlockInfo, Epoch>> l2Refs;

private BlockInfo safeHead;

private Epoch safeEpoch;
Expand All @@ -34,6 +43,7 @@ public class State {
*
* @param l1Info the L1 info
* @param l1Hashes the L1 hashes
* @param l2Refs the L2 block info references
* @param safeHead the safe head
* @param safeEpoch the safe epoch
* @param currentEpochNum the current epoch num
Expand All @@ -42,12 +52,14 @@ public class State {
public State(
TreeMap<String, L1Info> l1Info,
TreeMap<BigInteger, String> l1Hashes,
TreeMap<BigInteger, Tuple2<BlockInfo, Epoch>> l2Refs,
BlockInfo safeHead,
Epoch safeEpoch,
BigInteger currentEpochNum,
Config config) {
this.l1Info = l1Info;
this.l1Hashes = l1Hashes;
this.l2Refs = l2Refs;
this.safeHead = safeHead;
this.safeEpoch = safeEpoch;
this.currentEpochNum = currentEpochNum;
Expand All @@ -57,13 +69,19 @@ public State(
/**
* Create state.
*
* @param l2Refs the L2 block info references
* @param finalizedHead the finalized head
* @param finalizedEpoch the finalized epoch
* @param config the config
* @return the state
*/
public static State create(BlockInfo finalizedHead, Epoch finalizedEpoch, Config config) {
return new State(new TreeMap<>(), new TreeMap<>(), finalizedHead, finalizedEpoch, BigInteger.ZERO, config);
public static State create(
TreeMap<BigInteger, Tuple2<BlockInfo, Epoch>> l2Refs,
BlockInfo finalizedHead,
Epoch finalizedEpoch,
Config config) {
return new State(
new TreeMap<>(), new TreeMap<>(), l2Refs, finalizedHead, finalizedEpoch, BigInteger.ZERO, config);
}

/**
Expand All @@ -90,6 +108,20 @@ public L1Info l1Info(BigInteger number) {
return l1Info.get(l1Hashes.get(number));
}

/**
* Gets L2 block info and epoch by block timestamp.
*
* @param timestamp the number
* @return the tuple of L2 block info and epoch
*/
public Tuple2<BlockInfo, Epoch> l2Info(BigInteger timestamp) {
final BigInteger blockNum = timestamp
.subtract(config.chainConfig().l2Genesis().timestamp())
.divide(config.chainConfig().blockTime())
.add(config.chainConfig().l2Genesis().number());
return this.l2Refs.get(blockNum);
}

/**
* Epoch epoch.
*
Expand Down Expand Up @@ -146,6 +178,7 @@ public void purge(BlockInfo safeHead, Epoch safeEpoch) {
this.l1Info.clear();
this.l1Hashes.clear();
this.currentEpochNum = BigInteger.ZERO;
this.updateSafeHead(safeHead, safeEpoch);
}

/**
Expand All @@ -157,6 +190,7 @@ public void purge(BlockInfo safeHead, Epoch safeEpoch) {
public void updateSafeHead(BlockInfo safeHead, Epoch safeEpoch) {
this.safeHead = safeHead;
this.safeEpoch = safeEpoch;
this.l2Refs.put(safeHead.number(), new Tuple2<>(safeHead, safeEpoch));
}

/**
Expand Down Expand Up @@ -225,5 +259,63 @@ private void prune() {
this.l1Info.remove(blockNumAndHash.getValue());
this.l1Hashes.pollFirstEntry();
}

pruneUntil = this.safeHead
.number()
.subtract(this.config
.chainConfig()
.maxSeqDrift()
.divide(this.config.chainConfig().blockTime()));

Entry<BigInteger, Tuple2<BlockInfo, Epoch>> blockRefEntry;
while ((blockRefEntry = this.l2Refs.firstEntry()) != null) {
if (blockRefEntry.getKey().compareTo(pruneUntil) >= 0) {
break;
}
this.l2Refs.pollFirstEntry();
}
}

/**
* Init L2 refs tree map.
*
* @param headNum the l2 head block number
* @param chainConfig the chain config
* @param l2Client the l2 web3j client
* @return the L2 refs tree map.
* @throws ExecutionException throws the ExecutionException when the Task has been failed
* @throws InterruptedException throws the InterruptedException when the thread has been interrupted
*/
public static TreeMap<BigInteger, Tuple2<BlockInfo, Epoch>> initL2Refs(
BigInteger headNum, Config.ChainConfig chainConfig, Web3j l2Client)
throws ExecutionException, InterruptedException {
final BigInteger lookback = chainConfig.maxSeqDrift().divide(chainConfig.blockTime());
BigInteger start;
if (headNum.compareTo(lookback) < 0) {
start = chainConfig.l2Genesis().number();
} else {
start = headNum.subtract(lookback).max(chainConfig.l2Genesis().number());
}
final TreeMap<BigInteger, Tuple2<BlockInfo, Epoch>> l2Refs = new TreeMap<>();
for (BigInteger i = start; i.compareTo(headNum) <= 0; i = i.add(BigInteger.ONE)) {
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
var l2Num = i;
var blockTask =
scope.fork(() -> l2Client.ethGetBlockByNumber(DefaultBlockParameter.valueOf(l2Num), true)
.send()
.getBlock());
scope.join();
scope.throwIfFailed();
EthBlock.Block block = blockTask.get();
if (block == null) {
continue;
}
final HeadInfo l2BlockInfo = HeadInfo.from(block);
l2Refs.put(
l2BlockInfo.l2BlockInfo().number(),
new Tuple2<>(l2BlockInfo.l2BlockInfo(), l2BlockInfo.l1Epoch()));
}
}
return l2Refs;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import io.optimism.engine.ExecutionPayload.PayloadAttributes;
import io.optimism.l1.L1Info;
import io.optimism.utilities.derive.stages.Batch;
import io.optimism.utilities.derive.stages.SingularBatch;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.ArrayList;
Expand Down Expand Up @@ -78,7 +79,8 @@ public PayloadAttributes next() {
return batch != null ? this.deriveAttributes(batch) : null;
}

private PayloadAttributes deriveAttributes(Batch batch) {
private PayloadAttributes deriveAttributes(Batch batchWrapper) {
SingularBatch batch = (SingularBatch) batchWrapper.batch();
LOGGER.debug("attributes derived from block {}", batch.epochNum());
LOGGER.debug("batch epoch hash {}", batch.epochHash());

Expand All @@ -91,7 +93,7 @@ private PayloadAttributes deriveAttributes(Batch batch) {
batch.epochNum(), batch.epochHash(), l1Info.blockInfo().timestamp());

BigInteger timestamp = batch.timestamp();
BigInteger l1InclusionBlock = batch.l1InclusionBlock();
BigInteger l1InclusionBlock = batchWrapper.l1InclusionBlock();
BigInteger seqNumber = this.sequenceNumber;
String prevRandao = l1Info.blockInfo().mixHash();
List<String> transactions = this.deriveTransactions(batch, l1Info);
Expand Down Expand Up @@ -120,7 +122,7 @@ private PayloadAttributes deriveAttributes(Batch batch) {
seqNumber);
}

private List<String> deriveTransactions(Batch batch, L1Info l1Info) {
private List<String> deriveTransactions(SingularBatch batch, L1Info l1Info) {
List<String> transactions = new ArrayList<>();

String attributesTx = this.deriveAttributesDeposited(l1Info, batch.timestamp());
Expand Down
Loading
Loading