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

update besu-native libraries #1499

Merged
merged 9 commits into from
Oct 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* Prioritize high gas prices during mining. Previously we ordered only by the order in which the transactions were received. This will increase expected profit when mining. [\#1449](https://github.com/hyperledger/besu/pull/1449)
* Added support for the updated smart contract-based [node permissioning EEA interface](https://entethalliance.github.io/client-spec/spec.html#dfn-connectionallowed). [\#1435](https://github.com/hyperledger/besu/pull/1435)
* Added EvmTool binary to the distribution. EvmTool is a CLI that can execute EVM bytecode and execute ethereum state tests. [\#1465](https://github.com/hyperledger/besu/pull/1465)
* Updated the libraries for secp256k1 and AltBN series precompiles. These updates provide significant performance improvements to those areas. [\#1499](https://github.com/hyperledger/besu/pull/1499)

### Bug Fixes

Expand Down
4 changes: 2 additions & 2 deletions besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
import org.hyperledger.besu.ethereum.eth.sync.SyncMode;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.mainnet.precompiles.AltBN128PairingPrecompiledContract;
import org.hyperledger.besu.ethereum.mainnet.precompiles.AbstractAltBnPrecompiledContract;
import org.hyperledger.besu.ethereum.p2p.config.DiscoveryConfiguration;
import org.hyperledger.besu.ethereum.p2p.peers.EnodeDnsConfiguration;
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURL;
Expand Down Expand Up @@ -1269,7 +1269,7 @@ public static Optional<Boolean> getColorEnabled() {

private void configureNativeLibs() {
if (unstableNativeLibraryOptions.getNativeAltbn128()) {
AltBN128PairingPrecompiledContract.enableNative();
AbstractAltBnPrecompiledContract.enableNative();
}
if (unstableNativeLibraryOptions.getNativeSecp256k1()) {
SECP256K1.enableNative();
Expand Down
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ allprojects {
include '**/src/*/java/**/*.java'
exclude '**/generalstate/GeneralStateReferenceTest*.java'
exclude '**/generalstate/GeneralStateRegressionReferenceTest*.java'
exclude '**/generalstate/LegacyGeneralStateReferenceTest*.java'
exclude '**/blockchain/BlockchainReferenceTest*.java'
exclude '**/blockchain/LegacyBlockchainReferenceTest*.java'
exclude '**/.gradle/**'
}
removeUnusedImports()
Expand Down
1 change: 0 additions & 1 deletion ethereum/core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ dependencies {
implementation 'org.apache.logging.log4j:log4j-api'
implementation 'org.apache.tuweni:tuweni-bytes'
implementation 'org.apache.tuweni:tuweni-units'
implementation 'org.hyperledger.besu:altbn128'
implementation 'org.hyperledger.besu:bls12-381'
implementation 'org.immutables:value-annotations'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import org.hyperledger.besu.ethereum.core.Gas;
import org.hyperledger.besu.ethereum.vm.MessageFrame;

import javax.annotation.Nonnull;

import org.apache.tuweni.bytes.Bytes;

/**
Expand Down Expand Up @@ -50,5 +52,5 @@ public interface PrecompiledContract {
* @param messageFrame context for this message
* @return the output of the pre-compiled contract.
*/
Bytes compute(Bytes input, MessageFrame messageFrame);
Bytes compute(Bytes input, @Nonnull MessageFrame messageFrame);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
package org.hyperledger.besu.ethereum.mainnet.precompiles;

import static java.nio.charset.StandardCharsets.UTF_8;

import org.hyperledger.besu.ethereum.mainnet.AbstractPrecompiledContract;
import org.hyperledger.besu.ethereum.vm.GasCalculator;
import org.hyperledger.besu.ethereum.vm.MessageFrame;
import org.hyperledger.besu.nativelib.bls12_381.LibEthPairings;

import com.sun.jna.ptr.IntByReference;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tuweni.bytes.Bytes;

public abstract class AbstractAltBnPrecompiledContract extends AbstractPrecompiledContract {

private static final Logger LOG = LogManager.getLogger();
static boolean useNative = true;

public static void enableNative() {
useNative = LibEthPairings.ENABLED;
LOG.info(
useNative
? "Using LibEthPairings native alt bn128"
: "Native alt bn128 requested but not available");
}

private final byte operationId;

AbstractAltBnPrecompiledContract(
final String name, final GasCalculator gasCalculator, final byte operationId) {
super(name, gasCalculator);
this.operationId = operationId;
}

public Bytes computeNative(final Bytes input, final MessageFrame messageFrame) {
final byte[] result = new byte[LibEthPairings.EIP196_PREALLOCATE_FOR_RESULT_BYTES];
final byte[] error = new byte[LibEthPairings.EIP2537_PREALLOCATE_FOR_ERROR_BYTES];

final IntByReference o_len =
new IntByReference(LibEthPairings.EIP196_PREALLOCATE_FOR_RESULT_BYTES);
final IntByReference err_len =
new IntByReference(LibEthPairings.EIP2537_PREALLOCATE_FOR_ERROR_BYTES);
final int errorNo =
LibEthPairings.eip196_perform_operation(
operationId, input.toArrayUnsafe(), input.size(), result, o_len, error, err_len);
if (errorNo == 0) {
return Bytes.wrap(result, 0, o_len.getValue());
} 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);
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import org.hyperledger.besu.ethereum.vm.MessageFrame;
import org.hyperledger.besu.nativelib.bls12_381.LibEthPairings;

import javax.annotation.Nonnull;

import com.sun.jna.ptr.IntByReference;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
Expand Down Expand Up @@ -59,7 +61,7 @@ public String getName() {
}

@Override
public Bytes compute(final Bytes input, final MessageFrame messageFrame) {
public Bytes compute(final Bytes input, @Nonnull final MessageFrame messageFrame) {
final byte[] result = new byte[LibEthPairings.EIP2537_PREALLOCATE_FOR_RESULT_BYTES];
final byte[] error = new byte[LibEthPairings.EIP2537_PREALLOCATE_FOR_ERROR_BYTES];

Expand All @@ -73,11 +75,9 @@ public Bytes compute(final Bytes input, final MessageFrame messageFrame) {
if (errorNo == 0) {
return Bytes.wrap(result, 0, o_len.getValue());
} else {
final String errorMessage = new String(error, 0, err_len.getValue(), UTF_8);
messageFrame.setRevertReason(Bytes.wrap(error, 0, err_len.getValue()));
LOG.trace(
"Error executing precompiled contract {}: '{}'",
name,
new String(error, 0, err_len.getValue(), UTF_8));
LOG.trace("Error executing precompiled contract {}: '{}'", name, errorMessage);
return null;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,25 @@
*/
package org.hyperledger.besu.ethereum.mainnet.precompiles;

import static org.hyperledger.besu.nativelib.altbn128.LibAltbn128.altbn128_add_precompiled;

import org.hyperledger.besu.crypto.altbn128.AltBn128Point;
import org.hyperledger.besu.crypto.altbn128.Fq;
import org.hyperledger.besu.ethereum.core.Gas;
import org.hyperledger.besu.ethereum.mainnet.AbstractPrecompiledContract;
import org.hyperledger.besu.ethereum.vm.GasCalculator;
import org.hyperledger.besu.ethereum.vm.MessageFrame;
import org.hyperledger.besu.nativelib.bls12_381.LibEthPairings;

import java.math.BigInteger;
import java.util.Arrays;

import com.sun.jna.ptr.IntByReference;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.MutableBytes;

public class AltBN128AddPrecompiledContract extends AbstractPrecompiledContract {
public class AltBN128AddPrecompiledContract extends AbstractAltBnPrecompiledContract {

private final Gas gasCost;

private AltBN128AddPrecompiledContract(final GasCalculator gasCalculator, final Gas gasCost) {
super("AltBN128Add", gasCalculator);
super("AltBN128Add", gasCalculator, LibEthPairings.EIP196_ADD_OPERATION_RAW_VALUE);
this.gasCost = gasCost;
}

Expand All @@ -54,8 +51,8 @@ public Gas gasRequirement(final Bytes input) {

@Override
public Bytes compute(final Bytes input, final MessageFrame messageFrame) {
if (AltBN128PairingPrecompiledContract.useNative) {
return computeNative(input);
if (useNative) {
return computeNative(input, messageFrame);
} else {
return computeDefault(input);
}
Expand All @@ -82,16 +79,6 @@ private static Bytes computeDefault(final Bytes input) {
return result;
}

private static Bytes computeNative(final Bytes input) {
final byte[] output = new byte[64];
final IntByReference outputSize = new IntByReference(64);
if (altbn128_add_precompiled(input.toArrayUnsafe(), input.size(), output, outputSize) == 0) {
return Bytes.wrap(output, 0, outputSize.getValue());
} else {
return null;
}
}

private static BigInteger extractParameter(
final Bytes input, final int offset, final int length) {
if (offset > input.size() || length == 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,20 @@
*/
package org.hyperledger.besu.ethereum.mainnet.precompiles;

import static org.hyperledger.besu.nativelib.altbn128.LibAltbn128.altbn128_mul_precompiled;

import org.hyperledger.besu.crypto.altbn128.AltBn128Point;
import org.hyperledger.besu.crypto.altbn128.Fq;
import org.hyperledger.besu.ethereum.core.Gas;
import org.hyperledger.besu.ethereum.mainnet.AbstractPrecompiledContract;
import org.hyperledger.besu.ethereum.vm.GasCalculator;
import org.hyperledger.besu.ethereum.vm.MessageFrame;
import org.hyperledger.besu.nativelib.bls12_381.LibEthPairings;

import java.math.BigInteger;
import java.util.Arrays;

import com.sun.jna.ptr.IntByReference;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.MutableBytes;

public class AltBN128MulPrecompiledContract extends AbstractPrecompiledContract {
public class AltBN128MulPrecompiledContract extends AbstractAltBnPrecompiledContract {

private static final BigInteger MAX_N =
new BigInteger(
Expand All @@ -39,7 +36,7 @@ public class AltBN128MulPrecompiledContract extends AbstractPrecompiledContract
private final Gas gasCost;

private AltBN128MulPrecompiledContract(final GasCalculator gasCalculator, final Gas gasCost) {
super("AltBN128Mul", gasCalculator);
super("AltBN128Mul", gasCalculator, LibEthPairings.EIP196_MUL_OPERATION_RAW_VALUE);
this.gasCost = gasCost;
}

Expand All @@ -58,8 +55,8 @@ public Gas gasRequirement(final Bytes input) {

@Override
public Bytes compute(final Bytes input, final MessageFrame messageFrame) {
if (AltBN128PairingPrecompiledContract.useNative) {
return computeNative(input);
if (useNative) {
return computeNative(input, messageFrame);
} else {
return computeDefault(input);
}
Expand All @@ -85,16 +82,6 @@ private static Bytes computeDefault(final Bytes input) {
return result;
}

private static Bytes computeNative(final Bytes input) {
final byte[] output = new byte[64];
final IntByReference outputSize = new IntByReference(64);
if (altbn128_mul_precompiled(input.toArrayUnsafe(), input.size(), output, outputSize) == 0) {
return Bytes.wrap(output, 0, outputSize.getValue());
} else {
return null;
}
}

private static BigInteger extractParameter(
final Bytes input, final int offset, final int length) {
if (offset > input.size() || length == 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,25 @@
*/
package org.hyperledger.besu.ethereum.mainnet.precompiles;

import static org.hyperledger.besu.nativelib.altbn128.LibAltbn128.altbn128_pairing_precompiled;

import org.hyperledger.besu.crypto.altbn128.AltBn128Fq12Pairer;
import org.hyperledger.besu.crypto.altbn128.AltBn128Fq2Point;
import org.hyperledger.besu.crypto.altbn128.AltBn128Point;
import org.hyperledger.besu.crypto.altbn128.Fq;
import org.hyperledger.besu.crypto.altbn128.Fq12;
import org.hyperledger.besu.crypto.altbn128.Fq2;
import org.hyperledger.besu.ethereum.core.Gas;
import org.hyperledger.besu.ethereum.mainnet.AbstractPrecompiledContract;
import org.hyperledger.besu.ethereum.vm.GasCalculator;
import org.hyperledger.besu.ethereum.vm.MessageFrame;
import org.hyperledger.besu.nativelib.altbn128.LibAltbn128;
import org.hyperledger.besu.nativelib.bls12_381.LibEthPairings;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.sun.jna.ptr.IntByReference;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tuweni.bytes.Bytes;

public class AltBN128PairingPrecompiledContract extends AbstractPrecompiledContract {

static boolean useNative = true;

private static final Logger LOG = LogManager.getLogger();

public static void enableNative() {
useNative = LibAltbn128.ENABLED;
LOG.info(useNative ? "Using native alt bn128" : "Native alt bn128 requested but not available");
}
public class AltBN128PairingPrecompiledContract extends AbstractAltBnPrecompiledContract {

private static final int FIELD_LENGTH = 32;
private static final int PARAMETER_LENGTH = 192;
Expand All @@ -62,7 +47,7 @@ public static void enableNative() {

private AltBN128PairingPrecompiledContract(
final GasCalculator gasCalculator, final Gas pairingGasCost, final Gas baseGasCost) {
super("AltBN128Pairing", gasCalculator);
super("AltBN128Pairing", gasCalculator, LibEthPairings.EIP196_PAIR_OPERATION_RAW_VALUE);
this.pairingGasCost = pairingGasCost;
this.baseGasCost = baseGasCost;
}
Expand All @@ -89,8 +74,8 @@ public Bytes compute(final Bytes input, final MessageFrame messageFrame) {
if (input.size() % PARAMETER_LENGTH != 0) {
return null;
}
if (AltBN128PairingPrecompiledContract.useNative) {
return computeNative(input);
if (useNative) {
return computeNative(input, messageFrame);
} else {
return computeDefault(input);
}
Expand Down Expand Up @@ -134,17 +119,6 @@ private static Bytes computeDefault(final Bytes input) {
}
}

private static Bytes computeNative(final Bytes input) {
final byte[] output = new byte[32];
final IntByReference outputSize = new IntByReference(32);
if (altbn128_pairing_precompiled(input.toArrayUnsafe(), input.size(), output, outputSize)
== 0) {
return Bytes.wrap(output, 0, outputSize.getValue());
} else {
return null;
}
}

private static BigInteger extractParameter(
final Bytes input, final int offset, final int length) {
if (offset > input.size() || length == 0) {
Expand Down
Loading