Skip to content

Commit

Permalink
feat: beacon blob fetcher
Browse files Browse the repository at this point in the history
  • Loading branch information
thinkAfCod committed Feb 17, 2024
1 parent 1890e4e commit b6d4718
Show file tree
Hide file tree
Showing 4 changed files with 355 additions and 0 deletions.
112 changes: 112 additions & 0 deletions hildr-node/src/main/java/io/optimism/l1/BeaconBlobFetcher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package io.optimism.l1;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.optimism.type.BlobSidecar;
import io.optimism.type.SpecConfig;
import io.optimism.utilities.rpc.HttpClientProvider;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.math.BigInteger;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.StructuredTaskScope;

/**
* @author thinkAfCod
* @since 0.1.1
*/
public class BeaconBlobFetcher {

private static final String GENESIS_METHOD_FORMAT = "%s/eth/v1/beacon/genesis";

private static final String SPEC_METHOD_FORMAT = "%s/eth/v1/config/spec";

private static final String SIDECARS_METHOD_PREFIX_FORMAT = "%s/eth/v1/beacon/blob_sidecars";

private final String genesisMethod;

private final String specMethod;

private final String sidecarsMethod;

private final OkHttpClient httpClient;

private final ObjectMapper mapper;

/**
* Beacon blob info fetcher constructor.
*
* @param beaconUrl L1 beacon client url
*/
public BeaconBlobFetcher(String beaconUrl) {
this.genesisMethod = GENESIS_METHOD_FORMAT.formatted(beaconUrl);
this.specMethod = SPEC_METHOD_FORMAT.formatted(beaconUrl);
this.sidecarsMethod = SIDECARS_METHOD_PREFIX_FORMAT.formatted(beaconUrl);
this.httpClient = HttpClientProvider.create();
this.mapper = new ObjectMapper();
this.mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}

/**
* Get the genesis timestamp
*
* @return the genesis timestamp
*/
public BigInteger getGenesisTimestamp() {
var req = new Request.Builder().get().url(this.genesisMethod).build();
Map<String, Map<String, String>> res =
this.send(req, new TypeReference<>() {
});
return new BigInteger(res.get("data").get("genesis_time"));
}

/**
* Get the spec config
*
* @return the spec config
*/
public SpecConfig getSpecConfig() {
var req = new Request.Builder().get().url(this.specMethod).build();
return this.send(req, new TypeReference<>() {
});
}

/**
* Get the blob sidecars
*
* @param slot the block id
* @return the list of blob sidecars
*/
public List<BlobSidecar> getBlobSidecards(BigInteger slot) {
var req = new Request.Builder().get()
.url("%s/%d".formatted(this.sidecarsMethod, slot))
.build();
var res = this.send(req, new TypeReference<Map<String, List<BlobSidecar>>>() {
});
return res.get("data");
}

// todo
private <T> T send(final Request req, final TypeReference<T> typeRef) {
Call call = this.httpClient.newCall(req);
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
var task = scope.fork(() -> {
Response execute = call.execute();
return this.mapper.readValue(execute.body().byteStream(), typeRef);
});
scope.join();
scope.throwIfFailed();
return task.get();
} catch (InterruptedException | ExecutionException e) {

}
return null;
}

}
122 changes: 122 additions & 0 deletions hildr-utilities/src/main/java/io/optimism/type/BlobSidecar.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package io.optimism.type;

import java.math.BigInteger;

/**
* The BlobSidecar class
*
* @author thinkAfCod
* @since 0.2.6
*/
public class BlobSidecar {
private String blockRoot;
private String index;
private BigInteger slot;
private String blockParentRoot;
private BigInteger proposerIndex;
private String blob;
private String kzgCommitment;
private String kzgProof;

/**
* The BlobSidecar constructor.
*/
public BlobSidecar() {
}

/**
* The BlobSidecar constructor.
*
* @param blockRoot
* @param index
* @param slot
* @param blockParentRoot
* @param proposerIndex
* @param blob
* @param kzgCommitment
* @param kzgProof
*/
public BlobSidecar(
String blockRoot,
String index,
BigInteger slot,
String blockParentRoot,
BigInteger proposerIndex,
String blob,
String kzgCommitment,
String kzgProof
) {
this.blockRoot = blockRoot;
this.index = index;
this.slot = slot;
this.blockParentRoot = blockParentRoot;
this.proposerIndex = proposerIndex;
this.blob = blob;
this.kzgCommitment = kzgCommitment;
this.kzgProof = kzgProof;
}

public String getBlockRoot() {
return blockRoot;
}

public void setBlockRoot(String blockRoot) {
this.blockRoot = blockRoot;
}

public String getIndex() {
return index;
}

public void setIndex(String index) {
this.index = index;
}

public BigInteger getSlot() {
return slot;
}

public void setSlot(BigInteger slot) {
this.slot = slot;
}

public String getBlockParentRoot() {
return blockParentRoot;
}

public void setBlockParentRoot(String blockParentRoot) {
this.blockParentRoot = blockParentRoot;
}

public BigInteger getProposerIndex() {
return proposerIndex;
}

public void setProposerIndex(BigInteger proposerIndex) {
this.proposerIndex = proposerIndex;
}

public String getBlob() {
return blob;
}

public void setBlob(String blob) {
this.blob = blob;
}

public String getKzgCommitment() {
return kzgCommitment;
}

public void setKzgCommitment(String kzgCommitment) {
this.kzgCommitment = kzgCommitment;
}

public String getKzgProof() {
return kzgProof;
}

public void setKzgProof(String kzgProof) {
this.kzgProof = kzgProof;
}
}
93 changes: 93 additions & 0 deletions hildr-utilities/src/main/java/io/optimism/type/SpecConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package io.optimism.type;

import java.math.BigInteger;
import java.util.Objects;

/**
* @author thinkAfCod
* @since 0.1.1
*/
public class SpecConfig {
//{
// "DEPOSIT_CONTRACT_ADDRESS": "0x00000000219ab540356cBB839Cbe05303d7705Fa",
// "DEPOSIT_NETWORK_ID": "1",
// "DOMAIN_AGGREGATE_AND_PROOF": "0x06000000",
// "INACTIVITY_PENALTY_QUOTIENT": "67108864",
// "INACTIVITY_PENALTY_QUOTIENT_ALTAIR": "50331648"
//}
public String depositContractAddress;

public String depositNetworkId;

public String domainAggregateAndProof;

public String inactivityPenaltyQuotient;

public String inactivityPenaltyQuotientAltair;

public String getDepositContractAddress() {
return depositContractAddress;
}

public void setDepositContractAddress(String depositContractAddress) {
this.depositContractAddress = depositContractAddress;
}

public BigInteger getDepositNetworkId() {
return new BigInteger(depositNetworkId);
}

public void setDepositNetworkId(String depositNetworkId) {
this.depositNetworkId = depositNetworkId;
}

public BigInteger getDomainAggregateAndProof() {
return new BigInteger(domainAggregateAndProof);
}

public void setDomainAggregateAndProof(String domainAggregateAndProof) {
this.domainAggregateAndProof = domainAggregateAndProof;
}

public BigInteger getInactivityPenaltyQuotient() {
return new BigInteger(inactivityPenaltyQuotient);
}

public void setInactivityPenaltyQuotient(String inactivityPenaltyQuotient) {
this.inactivityPenaltyQuotient = inactivityPenaltyQuotient;
}

public BigInteger getInactivityPenaltyQuotientAltair() {
return new BigInteger(inactivityPenaltyQuotientAltair);
}

public String getInactivityPenaltyQuotientAltairRaw() {
return inactivityPenaltyQuotientAltair;
}

public void setInactivityPenaltyQuotientAltair(String inactivityPenaltyQuotientAltair) {
this.inactivityPenaltyQuotientAltair = inactivityPenaltyQuotientAltair;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SpecConfig that = (SpecConfig) o;
return Objects.equals(depositContractAddress, that.depositContractAddress)
&& Objects.equals(depositNetworkId, that.depositNetworkId)
&& Objects.equals(domainAggregateAndProof, that.domainAggregateAndProof)
&& Objects.equals(inactivityPenaltyQuotient, that.inactivityPenaltyQuotient)
&& Objects.equals(inactivityPenaltyQuotientAltair, that.inactivityPenaltyQuotientAltair);
}

@Override
public int hashCode() {
return Objects.hash(
depositContractAddress,
depositNetworkId,
domainAggregateAndProof,
inactivityPenaltyQuotient,
inactivityPenaltyQuotientAltair);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.optimism.utilities.rpc;

import okhttp3.OkHttpClient;

import java.time.Duration;

/**
* Http client provider.
*
* @author thinkAfCod
* @since 0.2.6
*/
public class HttpClientProvider {

private HttpClientProvider() {}

/**
* Create a http client.
*
* @return a HttpClient
*/
public static OkHttpClient create() {
return new OkHttpClient.Builder()
.addInterceptor(new RetryRateLimitInterceptor())
.build();
}

}

0 comments on commit b6d4718

Please sign in to comment.