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'