Skip to content

Commit

Permalink
Use existing Bytes48 for KZGCommitment and KZGProof (#5997)
Browse files Browse the repository at this point in the history
Signed-off-by: Fabio Di Fabio <[email protected]>
  • Loading branch information
fab-10 authored Oct 10, 2023
1 parent 9ec055c commit e946276
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@
import org.hyperledger.besu.ethereum.rlp.RLPInput;
import org.hyperledger.besu.ethereum.rlp.RLPOutput;

import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes48;

/** This class contains the data for a KZG commitment. */
public class KZGCommitment {
final Bytes data;
final Bytes48 data;

/**
* Constructor for a KZG commitment.
*
* @param data The data for the KZG commitment.
*/
public KZGCommitment(final Bytes data) {
public KZGCommitment(final Bytes48 data) {
this.data = data;
}

Expand All @@ -39,7 +39,7 @@ public KZGCommitment(final Bytes data) {
* @return The KZG commitment.
*/
public static KZGCommitment readFrom(final RLPInput input) {
final Bytes bytes = input.readBytes();
final Bytes48 bytes = input.readBytes48();
return new KZGCommitment(bytes);
}

Expand All @@ -57,7 +57,7 @@ public void writeTo(final RLPOutput out) {
*
* @return The data for the KZG commitment.
*/
public Bytes getData() {
public Bytes48 getData() {
return data;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@
import org.hyperledger.besu.ethereum.rlp.RLPInput;
import org.hyperledger.besu.ethereum.rlp.RLPOutput;

import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes48;

/** This class contains the data for a KZG proof for a KZG commitment. */
public class KZGProof {
final Bytes data;
final Bytes48 data;

/**
* Constructor for a KZG proof.
*
* @param data The data for the KZG proof.
*/
public KZGProof(final Bytes data) {
public KZGProof(final Bytes48 data) {
this.data = data;
}

Expand All @@ -39,7 +39,7 @@ public KZGProof(final Bytes data) {
* @return The KZG proof.
*/
public static KZGProof readFrom(final RLPInput input) {
final Bytes bytes = input.readBytes();
final Bytes48 bytes = input.readBytes48();
return new KZGProof(bytes);
}

Expand All @@ -57,7 +57,7 @@ public void writeTo(final RLPOutput out) {
*
* @return The data for the KZG proof.
*/
public Bytes getData() {
public Bytes48 getData() {
return data;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.bytes.Bytes48;
import org.junit.jupiter.api.Test;

public class BlobsWithCommitmentsTest {
Expand All @@ -45,9 +46,9 @@ public void blobsWithCommitmentsMustHaveSameNumberOfElementsVersionedHashes() {
InvalidParameterException.class,
() ->
new BlobsWithCommitments(
List.of(new KZGCommitment(Bytes.of(1))),
List.of(new KZGCommitment(Bytes48.fromHexStringLenient("1"))),
List.of(new Blob(Bytes.EMPTY)),
List.of(new KZGProof(Bytes.EMPTY)),
List.of(new KZGProof(Bytes48.ZERO)),
List.of()))
.getMessage();
final String expectedMessage =
Expand All @@ -64,7 +65,7 @@ public void blobsWithCommitmentsMustHaveSameNumberOfElementsKZGCommitment() {
new BlobsWithCommitments(
List.of(),
List.of(new Blob(Bytes.EMPTY)),
List.of(new KZGProof(Bytes.EMPTY)),
List.of(new KZGProof(Bytes48.ZERO)),
List.of(new VersionedHash(Bytes32.rightPad(Bytes.fromHexString("0x01"))))))
.getMessage();
final String expectedMessage =
Expand All @@ -79,7 +80,7 @@ public void blobsWithCommitmentsMustHaveSameNumberOfElementsKZGProof() {
InvalidParameterException.class,
() ->
new BlobsWithCommitments(
List.of(new KZGCommitment(Bytes.of(1))),
List.of(new KZGCommitment(Bytes48.fromHexStringLenient("1"))),
List.of(new Blob(Bytes.EMPTY)),
List.of(),
List.of(new VersionedHash(Bytes32.rightPad(Bytes.fromHexString("0x01"))))))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -927,17 +927,19 @@ public String toString() {
sb.append("nonce=").append(getNonce()).append(", ");
getGasPrice()
.ifPresent(
gasPrice -> sb.append("gasPrice=").append(gasPrice.toShortHexString()).append(", "));
gasPrice ->
sb.append("gasPrice=").append(gasPrice.toHumanReadableString()).append(", "));
if (getMaxPriorityFeePerGas().isPresent() && getMaxFeePerGas().isPresent()) {
sb.append("maxPriorityFeePerGas=")
.append(getMaxPriorityFeePerGas().map(Wei::toShortHexString).get())
.append(getMaxPriorityFeePerGas().map(Wei::toHumanReadableString).get())
.append(", ");
sb.append("maxFeePerGas=")
.append(getMaxFeePerGas().map(Wei::toShortHexString).get())
.append(getMaxFeePerGas().map(Wei::toHumanReadableString).get())
.append(", ");
getMaxFeePerBlobGas()
.ifPresent(
wei -> sb.append("maxFeePerBlobGas=").append(wei.toShortHexString()).append(", "));
wei ->
sb.append("maxFeePerBlobGas=").append(wei.toHumanReadableString()).append(", "));
}
sb.append("gasLimit=").append(getGasLimit()).append(", ");
if (getTo().isPresent()) sb.append("to=").append(getTo().get()).append(", ");
Expand Down Expand Up @@ -993,7 +995,7 @@ public String toTraceLog() {
}
sb.append("gl: ").append(getGasLimit()).append(", ");
sb.append("v: ").append(getValue().toHumanReadableString()).append(", ");
getTo().ifPresent(to -> sb.append(to));
getTo().ifPresent(to -> sb.append("to: ").append(to));
return sb.append("}").toString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,12 +339,11 @@ public TransactionProcessingResult processTransaction(
gasCalculator.accessListGasCost(accessListEntries.size(), accessListStorageCount);
final long gasAvailable = transaction.getGasLimit() - intrinsicGas - accessListGas;
LOG.trace(
"Gas available for execution {} = {} - {} - {} - {} (limit - intrinsic - accessList - data)",
"Gas available for execution {} = {} - {} - {} (limit - intrinsic - accessList)",
gasAvailable,
transaction.getGasLimit(),
intrinsicGas,
accessListGas,
blobGas);
accessListGas);

final WorldUpdater worldUpdater = worldState.updater();
final ImmutableMap.Builder<String, Object> contextVariablesBuilder =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.hyperledger.besu.datatypes.BlobsWithCommitments;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.KZGCommitment;
import org.hyperledger.besu.datatypes.KZGProof;
import org.hyperledger.besu.datatypes.TransactionType;
import org.hyperledger.besu.datatypes.VersionedHash;
import org.hyperledger.besu.datatypes.Wei;
Expand Down Expand Up @@ -51,8 +50,6 @@
*/
public class MainnetTransactionValidator implements TransactionValidator {

private static final byte BLOB_COMMITMENT_VERSION_KZG = 0x01;

private final GasCalculator gasCalculator;
private final GasLimitCalculator gasLimitCalculator;
private final FeeMarket feeMarket;
Expand Down Expand Up @@ -336,11 +333,11 @@ public ValidationResult<TransactionInvalidReason> validateTransactionsBlobs(
final KZGCommitment commitment = blobsWithCommitments.getKzgCommitments().get(i);
final VersionedHash versionedHash = versionedHashes.get(i);

if (versionedHash.getVersionId() != BLOB_COMMITMENT_VERSION_KZG) {
if (versionedHash.getVersionId() != VersionedHash.SHA256_VERSION_ID) {
return ValidationResult.invalid(
TransactionInvalidReason.INVALID_BLOBS,
"transaction blobs commitment version is not supported. Expected "
+ BLOB_COMMITMENT_VERSION_KZG
+ VersionedHash.SHA256_VERSION_ID
+ ", found "
+ versionedHash.getVersionId());
}
Expand All @@ -353,30 +350,27 @@ public ValidationResult<TransactionInvalidReason> validateTransactionsBlobs(
}
}

final Bytes blobs =
blobsWithCommitments.getBlobs().stream()
.map(Blob::getData)
.reduce(Bytes::concatenate)
.orElseThrow();
final byte[] blobs =
Bytes.wrap(blobsWithCommitments.getBlobs().stream().map(Blob::getData).toList())
.toArrayUnsafe();

final Bytes kzgCommitments =
blobsWithCommitments.getKzgCommitments().stream()
.map(KZGCommitment::getData)
.reduce(Bytes::concatenate)
.orElseThrow();
final byte[] kzgCommitments =
Bytes.wrap(
blobsWithCommitments.getKzgCommitments().stream()
.map(kc -> (Bytes) kc.getData())
.toList())
.toArrayUnsafe();

final Bytes kzgProofs =
blobsWithCommitments.getKzgProofs().stream()
.map(KZGProof::getData)
.reduce(Bytes::concatenate)
.orElseThrow();
final byte[] kzgProofs =
Bytes.wrap(
blobsWithCommitments.getKzgProofs().stream()
.map(kp -> (Bytes) kp.getData())
.toList())
.toArrayUnsafe();

final boolean kzgVerification =
CKZG4844JNI.verifyBlobKzgProofBatch(
blobs.toArrayUnsafe(),
kzgCommitments.toArrayUnsafe(),
kzgProofs.toArrayUnsafe(),
blobsWithCommitments.getBlobs().size());
blobs, kzgCommitments, kzgProofs, blobsWithCommitments.getBlobs().size());

if (!kzgVerification) {
return ValidationResult.invalid(
Expand All @@ -387,14 +381,6 @@ public ValidationResult<TransactionInvalidReason> validateTransactionsBlobs(
return ValidationResult.valid();
}

/*
private VersionedHash hashCommitment(final Bytes32 commitment) {
return new VersionedHash(
VersionedHash.SHA256_VERSION_ID, Sha256Hash.hash(commitment));
}
*/

private VersionedHash hashCommitment(final KZGCommitment commitment) {
final SHA256Digest digest = new SHA256Digest();
digest.update(commitment.getData().toArrayUnsafe(), 0, commitment.getData().size());
Expand All @@ -403,7 +389,7 @@ private VersionedHash hashCommitment(final KZGCommitment commitment) {

digest.doFinal(dig, 0);

dig[0] = BLOB_COMMITMENT_VERSION_KZG;
dig[0] = VersionedHash.SHA256_VERSION_ID;
return new VersionedHash(Bytes32.wrap(dig));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

package org.hyperledger.besu.ethereum.core;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;

import org.hyperledger.besu.datatypes.Blob;
Expand All @@ -33,6 +32,7 @@
import ethereum.ckzg4844.CKZG4844JNI;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.bytes.Bytes48;
import org.bouncycastle.crypto.digests.SHA256Digest;

public class BlobTestFixture {
Expand Down Expand Up @@ -68,10 +68,10 @@ public BlobTriplet createBlobTriplet() {
fail("Failed to read blob file", e);
}

Bytes commitment = Bytes.wrap(CKZG4844JNI.blobToKzgCommitment(rawMaterial));
Bytes48 commitment = Bytes48.wrap(CKZG4844JNI.blobToKzgCommitment(rawMaterial));

assertThat(commitment.size()).isEqualTo(48);
Bytes proof = Bytes.wrap(CKZG4844JNI.computeBlobKzgProof(rawMaterial, commitment.toArray()));
Bytes48 proof =
Bytes48.wrap(CKZG4844JNI.computeBlobKzgProof(rawMaterial, commitment.toArray()));
VersionedHash versionedHash = hashCommitment(new KZGCommitment(commitment));
return new BlobTriplet(
new Blob(Bytes.wrap(rawMaterial)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@

import com.google.common.base.Suppliers;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes48;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
Expand Down Expand Up @@ -503,9 +504,9 @@ public void shouldRejectContractCreateWithBlob() {
.blobsWithCommitments(
Optional.of(
new BlobsWithCommitments(
List.of(new KZGCommitment(Bytes.EMPTY)),
List.of(new KZGCommitment(Bytes48.ZERO)),
List.of(new Blob(Bytes.EMPTY)),
List.of(new KZGProof(Bytes.EMPTY)),
List.of(new KZGProof(Bytes48.ZERO)),
List.of(VersionedHash.DEFAULT_VERSIONED_HASH))))
.versionedHashes(Optional.of(List.of(VersionedHash.DEFAULT_VERSIONED_HASH)))
.createTransaction(senderKeys);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.bytes.Bytes48;
import org.apache.tuweni.bytes.MutableBytes;
import org.apache.tuweni.bytes.MutableBytes32;
import org.apache.tuweni.units.bigints.UInt256;
Expand Down Expand Up @@ -98,6 +99,8 @@ protected void init(final long inputSize, final boolean shouldFitInputSizeExactl

protected abstract Bytes32 inputSlice32(long offset);

protected abstract Bytes48 inputSlice48(long offset);

protected abstract String inputHex(long offset, int length);

protected abstract BigInteger getUnsignedBigInteger(long offset, int length);
Expand Down Expand Up @@ -426,6 +429,14 @@ public Bytes32 readBytes32() {
return res;
}

@Override
public Bytes48 readBytes48() {
checkElt("48 bytes value", 48);
final Bytes48 res = inputSlice48(currentPayloadOffset);
setTo(nextItem());
return res;
}

@Override
public <T> T readBytes(final Function<Bytes, T> mapper) {
final Bytes res = readBytes();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.bytes.Bytes48;

/** An {@link RLPInput} that reads RLP encoded data from a {@link Bytes}. */
public class BytesValueRLPInput extends AbstractRLPInput {
Expand Down Expand Up @@ -51,6 +52,11 @@ protected Bytes32 inputSlice32(final long offset) {
return Bytes32.wrap(inputSlice(offset, 32));
}

@Override
protected Bytes48 inputSlice48(final long offset) {
return Bytes48.wrap(inputSlice(offset, 48));
}

@Override
protected String inputHex(final long offset, final int length) {
return value.slice(Math.toIntExact(offset), length).toString().substring(2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.bytes.Bytes48;
import org.apache.tuweni.units.bigints.UInt256;
import org.apache.tuweni.units.bigints.UInt64;

Expand Down Expand Up @@ -300,6 +301,16 @@ default long readUnsignedInt() {
*/
Bytes32 readBytes32();

/**
* Reads the next item of this input (assuming it is not a list) that must be exact 48 bytes.
*
* @return The next item read of this input.
* @throws RLPException if the next item to read is a list, the input is at the end of its current
* list (and {@link #leaveList()} hasn't been called) or the next element is not exactly 48
* bytes.
*/
Bytes48 readBytes48();

/**
* Reads the next item of this input (assuming it is not a list) and transforms it with the
* provided mapping function.
Expand Down

0 comments on commit e946276

Please sign in to comment.