diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5e222fa86c8..c850d7c2e5b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,7 @@
- Fast Sync
### Additions and Improvements
+- Performance: Optimise EIP-196 AltBn128: EcAdd 33-128% faster, EcMul 8% faster [#9570](https://github.com/hyperledger/besu/pull/9570)
## 25.12.0
diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractAltBnPrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractAltBnPrecompiledContract.java
index 5877acf7228..330641a832a 100644
--- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractAltBnPrecompiledContract.java
+++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractAltBnPrecompiledContract.java
@@ -23,7 +23,6 @@
import java.util.Optional;
-import com.sun.jna.ptr.IntByReference;
import jakarta.validation.constraints.NotNull;
import org.apache.tuweni.bytes.Bytes;
import org.slf4j.Logger;
@@ -73,6 +72,7 @@ public static boolean isNative() {
private final byte operationId;
private final int inputLimit;
+ private final int outputLength;
/**
* Instantiates a new Abstract alt bn precompiled contract.
@@ -81,15 +81,18 @@ public static boolean isNative() {
* @param gasCalculator the gas calculator
* @param operationId the operation id
* @param inputLen the input len
+ * @param outputLen the output len
*/
AbstractAltBnPrecompiledContract(
final String name,
final GasCalculator gasCalculator,
final byte operationId,
- final int inputLen) {
+ final int inputLen,
+ final int outputLen) {
super(name, gasCalculator);
this.operationId = operationId;
this.inputLimit = inputLen + 1;
+ this.outputLength = outputLen;
if (!LibGnarkEIP196.ENABLED) {
LOG.info("Native alt bn128 not available");
@@ -107,29 +110,17 @@ public static boolean isNative() {
public PrecompileContractResult computeNative(
final @NotNull Bytes input, final MessageFrame messageFrame) {
final byte[] result = new byte[LibGnarkEIP196.EIP196_PREALLOCATE_FOR_RESULT_BYTES];
- final byte[] error = new byte[LibGnarkEIP196.EIP196_PREALLOCATE_FOR_ERROR_BYTES];
- final IntByReference o_len =
- new IntByReference(LibGnarkEIP196.EIP196_PREALLOCATE_FOR_RESULT_BYTES);
- final IntByReference err_len =
- new IntByReference(LibGnarkEIP196.EIP196_PREALLOCATE_FOR_ERROR_BYTES);
final int inputSize = Math.min(inputLimit, input.size());
final int errorNo =
LibGnarkEIP196.eip196_perform_operation(
- operationId,
- input.slice(0, inputSize).toArrayUnsafe(),
- inputSize,
- result,
- o_len,
- error,
- err_len);
-
- if (errorNo == 0) {
- return PrecompileContractResult.success(Bytes.wrap(result, 0, o_len.getValue()));
+ operationId, input.slice(0, inputSize).toArrayUnsafe(), inputSize, result);
+
+ if (errorNo == LibGnarkEIP196.EIP196_ERR_CODE_SUCCESS) {
+ return PrecompileContractResult.success(Bytes.wrap(result, 0, outputLength));
} else {
- final String errorString = new String(error, 0, err_len.getValue(), UTF_8);
- messageFrame.setRevertReason(Bytes.wrap(error, 0, err_len.getValue()));
- LOG.trace("Error executing precompiled contract {}: '{}'", getName(), errorString);
+ messageFrame.setRevertReason(Bytes.wrap("error".getBytes(UTF_8)));
+ LOG.debug("Error executing precompiled contract {}: '{}'", getName(), errorNo);
return PrecompileContractResult.halt(
null, Optional.of(ExceptionalHaltReason.PRECOMPILE_ERROR));
}
diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128AddPrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128AddPrecompiledContract.java
index ff49626cde7..b52d4c48aa9 100644
--- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128AddPrecompiledContract.java
+++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128AddPrecompiledContract.java
@@ -48,7 +48,8 @@ public class AltBN128AddPrecompiledContract extends AbstractAltBnPrecompiledCont
PRECOMPILE_NAME,
gasCalculator,
LibGnarkEIP196.EIP196_ADD_OPERATION_RAW_VALUE,
- PARAMETER_LENGTH);
+ PARAMETER_LENGTH,
+ LibGnarkEIP196.EIP196_PREALLOCATE_FOR_RESULT_BYTES);
this.gasCost = gasCost;
}
diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128MulPrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128MulPrecompiledContract.java
index 8f0d13714bf..118175e787a 100644
--- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128MulPrecompiledContract.java
+++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128MulPrecompiledContract.java
@@ -54,7 +54,8 @@ public class AltBN128MulPrecompiledContract extends AbstractAltBnPrecompiledCont
PRECOMPILE_NAME,
gasCalculator,
LibGnarkEIP196.EIP196_MUL_OPERATION_RAW_VALUE,
- PARAMETER_LENGTH);
+ PARAMETER_LENGTH,
+ LibGnarkEIP196.EIP196_PREALLOCATE_FOR_RESULT_BYTES);
this.gasCost = gasCost;
}
diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128PairingPrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128PairingPrecompiledContract.java
index 606dfe4b9ee..24046426761 100644
--- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128PairingPrecompiledContract.java
+++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128PairingPrecompiledContract.java
@@ -71,7 +71,9 @@ public class AltBN128PairingPrecompiledContract extends AbstractAltBnPrecompiled
PRECOMPILE_NAME,
gasCalculator,
LibGnarkEIP196.EIP196_PAIR_OPERATION_RAW_VALUE,
- Integer.MAX_VALUE / PARAMETER_LENGTH * PARAMETER_LENGTH);
+ (Integer.MAX_VALUE / PARAMETER_LENGTH)
+ * PARAMETER_LENGTH, // round down to nearest multiple of 192
+ LibGnarkEIP196.EIP196_PAIR_PREALLOCATE_FOR_RESULT_BYTES);
this.pairingGasCost = pairingGasCost;
this.baseGasCost = baseGasCost;
}
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index ae24b94872e..59f1f567565 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -4821,20 +4821,12 @@
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
@@ -4845,116 +4837,60 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
diff --git a/platform/build.gradle b/platform/build.gradle
index 7f473ac6300..9ac422fc843 100644
--- a/platform/build.gradle
+++ b/platform/build.gradle
@@ -145,15 +145,14 @@ dependencies {
api 'org.hibernate.validator:hibernate-validator:8.0.2.Final'
- api 'org.hyperledger.besu:besu-native-common:1.4.1'
- api 'org.hyperledger.besu:arithmetic:1.4.1'
- api 'org.hyperledger.besu:blake2bf:1.4.1'
- api 'org.hyperledger.besu:gnark:1.4.1'
- api 'org.hyperledger.besu:ipa-multipoint:1.4.1'
- api 'org.hyperledger.besu:secp256k1:1.4.1'
- api 'org.hyperledger.besu:secp256r1:1.4.1'
- api 'org.hyperledger.besu:boringssl:1.4.1'
-
+ api 'org.hyperledger.besu:besu-native-common:1.4.2'
+ api 'org.hyperledger.besu:arithmetic:1.4.2'
+ api 'org.hyperledger.besu:blake2bf:1.4.2'
+ api 'org.hyperledger.besu:gnark:1.4.2'
+ api 'org.hyperledger.besu:ipa-multipoint:1.4.2'
+ api 'org.hyperledger.besu:secp256k1:1.4.2'
+ api 'org.hyperledger.besu:secp256r1:1.4.2'
+ api 'org.hyperledger.besu:boringssl:1.4.2'
api 'org.hyperledger.besu:besu-errorprone-checks:1.2.0'
api 'org.jacoco:org.jacoco.agent:0.8.12'