Change Array Copying (#5998) (#6002)

* Change Array Copying

Change array copying by re-using arrays when safe.



* spotless



* different bigint API



* straddle case



* less stack traces



* spotless



---------

Signed-off-by: Danno Ferrin <danno.ferrin@swirldslabs.com>
Co-authored-by: Danno Ferrin <danno.ferrin@swirldslabs.com>
pull/6006/head
Fabio Di Fabio 1 year ago committed by GitHub
parent 1f976af446
commit 44a7742aaf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java
  2. 2
      ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/BlockchainReferenceTestTools.java
  3. 4
      evm/src/main/java/org/hyperledger/besu/evm/frame/Memory.java
  4. 28
      evm/src/main/java/org/hyperledger/besu/evm/internal/Words.java
  5. 2
      evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128MulPrecompiledContract.java
  6. 2
      evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128PairingPrecompiledContract.java
  7. 2
      evm/src/main/java/org/hyperledger/besu/evm/precompile/BLAKE2BFPrecompileContract.java
  8. 12
      evm/src/main/java/org/hyperledger/besu/evm/precompile/BigIntegerModularExponentiationPrecompiledContract.java
  9. 2
      evm/src/main/java/org/hyperledger/besu/evm/precompile/KZGPointEvalPrecompiledContract.java
  10. 3
      evm/src/test/java/org/hyperledger/besu/evm/toy/EvmToyCommand.java
  11. 2
      gradle.properties

@ -424,7 +424,8 @@ public class EvmToolCommand implements Runnable {
out.println(messageFrame.getExceptionalHaltReason().get()); out.println(messageFrame.getExceptionalHaltReason().get());
} }
if (messageFrame.getRevertReason().isPresent()) { if (messageFrame.getRevertReason().isPresent()) {
out.println(new String(messageFrame.getRevertReason().get().toArray(), UTF_8)); out.println(
new String(messageFrame.getRevertReason().get().toArrayUnsafe(), UTF_8));
} }
} }
} }

@ -87,7 +87,7 @@ public class BlockchainReferenceTestTools {
params.ignore("blockWithAllTransactionTypes"); params.ignore("blockWithAllTransactionTypes");
// EIP-4788 is still in flux and the current fill is not against the final address // EIP-4788 is still in flux and the current fill is not against the final address
params.ignore("[Cancun]"); params.ignore("\\[Cancun\\]");
// EOF tests are written against an older version of the spec // EOF tests are written against an older version of the spec
params.ignore("/stEOF/"); params.ignore("/stEOF/");

@ -14,6 +14,8 @@
*/ */
package org.hyperledger.besu.evm.frame; package org.hyperledger.besu.evm.frame;
import org.hyperledger.besu.evm.internal.Words;
import java.util.Arrays; import java.util.Arrays;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
@ -100,7 +102,7 @@ public class Memory {
} }
try { try {
final long byteSize = Math.addExact(Math.addExact(location, numBytes), 31); final long byteSize = Words.clampedAdd(Words.clampedAdd(location, numBytes), 31);
long wordSize = byteSize / 32; long wordSize = byteSize / 32;
return Math.max(wordSize, activeWords); return Math.max(wordSize, activeWords);
} catch (ArithmeticException ae) { } catch (ArithmeticException ae) {

@ -117,10 +117,12 @@ public interface Words {
* @return value of a plus b if no over/underflows or Long.MAX_VALUE/Long.MIN_VALUE otherwise * @return value of a plus b if no over/underflows or Long.MAX_VALUE/Long.MIN_VALUE otherwise
*/ */
static long clampedAdd(final long a, final long b) { static long clampedAdd(final long a, final long b) {
try { long r = a + b;
return Math.addExact(a, b); if (((a ^ r) & (b ^ r)) < 0) {
} catch (final ArithmeticException ae) { // out of bounds, clamp it!
return a > 0 ? Long.MAX_VALUE : Long.MIN_VALUE; return a > 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
} else {
return r;
} }
} }
@ -132,10 +134,15 @@ public interface Words {
* @return value of a times b if no over/underflows or Long.MAX_VALUE/Long.MIN_VALUE otherwise * @return value of a times b if no over/underflows or Long.MAX_VALUE/Long.MIN_VALUE otherwise
*/ */
static long clampedMultiply(final long a, final long b) { static long clampedMultiply(final long a, final long b) {
try { long r = a * b;
return Math.multiplyExact(a, b); long ax = Math.abs(a);
} catch (final ArithmeticException ae) { long ay = Math.abs(b);
if (((ax | ay) >>> 31 != 0)
&& (((b != 0) && (r / b != a)) || (a == Long.MIN_VALUE && b == -1))) {
// out of bounds, clamp it!
return ((a ^ b) < 0) ? Long.MIN_VALUE : Long.MAX_VALUE; return ((a ^ b) < 0) ? Long.MIN_VALUE : Long.MAX_VALUE;
} else {
return r;
} }
} }
@ -148,9 +155,12 @@ public interface Words {
* otherwise * otherwise
*/ */
static int clampedMultiply(final int a, final int b) { static int clampedMultiply(final int a, final int b) {
try { long r = (long) a * (long) b;
return Math.multiplyExact(a, b); int ri = (int) r;
} catch (final ArithmeticException ae) { if (ri == r) {
return ri;
} else {
// out of bounds, clamp it!
return ((a ^ b) < 0) ? Integer.MIN_VALUE : Integer.MAX_VALUE; return ((a ^ b) < 0) ? Integer.MIN_VALUE : Integer.MAX_VALUE;
} }
} }

@ -112,7 +112,7 @@ public class AltBN128MulPrecompiledContract extends AbstractAltBnPrecompiledCont
if (offset > input.size() || length == 0) { if (offset > input.size() || length == 0) {
return BigInteger.ZERO; return BigInteger.ZERO;
} }
final byte[] raw = Arrays.copyOfRange(input.toArray(), offset, offset + length); final byte[] raw = Arrays.copyOfRange(input.toArrayUnsafe(), offset, offset + length);
return new BigInteger(1, raw); return new BigInteger(1, raw);
} }
} }

@ -151,7 +151,7 @@ public class AltBN128PairingPrecompiledContract extends AbstractAltBnPrecompiled
if (offset > input.size() || length == 0) { if (offset > input.size() || length == 0) {
return BigInteger.ZERO; return BigInteger.ZERO;
} }
final byte[] raw = Arrays.copyOfRange(input.toArray(), offset, offset + length); final byte[] raw = Arrays.copyOfRange(input.toArrayUnsafe(), offset, offset + length);
return new BigInteger(1, raw); return new BigInteger(1, raw);
} }
} }

@ -57,7 +57,7 @@ public class BLAKE2BFPrecompileContract extends AbstractPrecompiledContract {
return 0L; return 0L;
} }
final byte[] roundsBytes = copyOfRange(input.toArray(), 0, 4); final byte[] roundsBytes = copyOfRange(input.toArrayUnsafe(), 0, 4);
final BigInteger rounds = new BigInteger(1, roundsBytes); final BigInteger rounds = new BigInteger(1, roundsBytes);
return rounds.longValueExact(); return rounds.longValueExact();
} }

@ -25,7 +25,6 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.nativelib.arithmetic.LibArithmetic; import org.hyperledger.besu.nativelib.arithmetic.LibArithmetic;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Arrays;
import java.util.Optional; import java.util.Optional;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -200,11 +199,16 @@ public class BigIntegerModularExponentiationPrecompiledContract
* @return the big integer * @return the big integer
*/ */
public static BigInteger extractParameter(final Bytes input, final int offset, final int length) { public static BigInteger extractParameter(final Bytes input, final int offset, final int length) {
if (offset > input.size() || length == 0) { if (offset >= input.size() || length == 0) {
return BigInteger.ZERO; return BigInteger.ZERO;
} else if (offset + length < input.size()) {
return new BigInteger(1, input.slice(offset, length).toArray());
} else {
byte[] raw = new byte[length];
Bytes partial = input.slice(offset);
System.arraycopy(partial.toArray(), 0, raw, 0, partial.size());
return new BigInteger(1, raw);
} }
final byte[] raw = Arrays.copyOfRange(input.toArray(), offset, offset + length);
return new BigInteger(1, raw);
} }
/** /**

@ -115,7 +115,7 @@ public class KZGPointEvalPrecompiledContract implements PrecompiledContract {
return PrecompileContractResult.halt( return PrecompileContractResult.halt(
null, Optional.of(ExceptionalHaltReason.PRECOMPILE_ERROR)); null, Optional.of(ExceptionalHaltReason.PRECOMPILE_ERROR));
} else { } else {
byte[] hash = Hash.sha256(commitment).toArray(); byte[] hash = Hash.sha256(commitment).toArrayUnsafe();
hash[0] = 0x01; hash[0] = 0x01;
if (!versionedHash.equals(Bytes32.wrap(hash))) { if (!versionedHash.equals(Bytes32.wrap(hash))) {
return PrecompileContractResult.halt( return PrecompileContractResult.halt(

@ -211,7 +211,8 @@ public class EvmToyCommand implements Runnable {
} }
if (messageFrame.getRevertReason().isPresent()) { if (messageFrame.getRevertReason().isPresent()) {
out.println( out.println(
new String(messageFrame.getRevertReason().get().toArray(), StandardCharsets.UTF_8)); new String(
messageFrame.getRevertReason().get().toArrayUnsafe(), StandardCharsets.UTF_8));
} }
} }
if (messageFrameStack.isEmpty()) { if (messageFrameStack.isEmpty()) {

@ -1,4 +1,4 @@
version=23.10.0-RC version=23.10.0-RC2
org.gradle.welcome=never org.gradle.welcome=never
# Set exports/opens flags required by Google Java Format and ErrorProne plugins. (JEP-396) # Set exports/opens flags required by Google Java Format and ErrorProne plugins. (JEP-396)

Loading…
Cancel
Save