Skip to content
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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*.iml
*.launch
*.log
*.orig
.classpath
.claude
.DS_Store
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ are provided with different values, using input as per the execution-apis spec i
- Add maxUsedGas field to eth_simulateV1 results [#10066](https://github.com/besu-eth/besu/pull/10066)
- Plugin API: pass pending block header when creating selectors [#10034](https://github.com/besu-eth/besu/pull/10034)

### Performance
- UInt256 arithmetics with long limbs [#9677](https://github.com/besu-eth/besu/pull/9677)
- Fix edge case in MOD variant operations regarding multiply subtract step [#9934](https://github.com/besu-eth/besu/pull/9934)
- Fix addMod case with 256bit moduluses [#10001](https://github.com/besu-eth/besu/pull/10001)
- Performance improvements on MOD variant instructions while converting from byte[] to longs [#9976](https://github.com/besu-eth/besu/pull/9976)
- Implement DIV and SDIV with long limbs [#9923](https://github.com/besu-eth/besu/pull/9923)

## 26.2.0

### Breaking Changes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,119 @@
package org.hyperledger.besu.ethereum.vm.operations;

import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.operation.DivOperation;
import org.hyperledger.besu.evm.operation.DivOperationOptimized;
import org.hyperledger.besu.evm.operation.Operation;

import java.math.BigInteger;
import java.util.Random;

import org.apache.tuweni.bytes.Bytes;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Setup;

public class DivOperationBenchmark extends BinaryOperationBenchmark {

public enum Case {
DIV_32_32(1, 1),
DIV_64_32(2, 1),
DIV_64_64(2, 2),
DIV_128_32(4, 1),
DIV_128_64(4, 2),
DIV_128_128(4, 4),
DIV_192_32(6, 1),
DIV_192_64(6, 2),
DIV_192_128(6, 4),
DIV_192_192(6, 6),
DIV_256_32(8, 1),
DIV_256_64(8, 2),
DIV_256_128(8, 4),
DIV_256_192(8, 6),
DIV_256_256(8, 8),
DIV_ZERO_QUOTIENT_0_256(0, 8),
DIV_ZERO_QUOTIENT_64_256(2, 8),
DIV_ZERO_QUOTIENT_128_256(4, 8),
DIV_ZERO_QUOTIENT_192_256(6, 8),
DIV_FULL_RANDOM(-1, -1);

final int numSize;
final int denomSize;

Case(final int numSize, final int denomSize) {
this.numSize = numSize;
this.denomSize = denomSize;
}
}

@Param({
"DIV_32_32",
"DIV_64_32",
"DIV_64_64",
"DIV_128_32",
"DIV_128_64",
"DIV_128_128",
"DIV_192_32",
"DIV_192_64",
"DIV_192_128",
"DIV_192_192",
"DIV_256_32",
"DIV_256_64",
"DIV_256_128",
"DIV_256_192",
"DIV_256_256",
"DIV_ZERO_QUOTIENT_0_256",
"DIV_ZERO_QUOTIENT_64_256",
"DIV_ZERO_QUOTIENT_128_256",
"DIV_ZERO_QUOTIENT_192_256",
"DIV_FULL_RANDOM"
})
private String caseName;

@Setup(Level.Iteration)
@Override
public void setUp() {
frame = BenchmarkHelper.createMessageCallFrame();

Case scenario = Case.valueOf(caseName);
aPool = new Bytes[SAMPLE_SIZE];
bPool = new Bytes[SAMPLE_SIZE];

final Random random = new Random();
int aSize;
int bSize;

for (int i = 0; i < SAMPLE_SIZE; i++) {
if (scenario.numSize < 0) aSize = random.nextInt(1, 33);
else aSize = scenario.numSize * 4;
if (scenario.denomSize < 0) bSize = random.nextInt(1, 33);
else bSize = scenario.denomSize * 4;

final byte[] a = new byte[aSize];
final byte[] b = new byte[bSize];
random.nextBytes(a);
random.nextBytes(b);

// Swap a and b if necessary
if ((scenario.numSize != scenario.denomSize)) {
aPool[i] = Bytes.wrap(a);
bPool[i] = Bytes.wrap(b);
} else {
BigInteger aInt = new BigInteger(1, a);
BigInteger bInt = new BigInteger(1, b);
if ((aInt.compareTo(bInt) < 0)) {
aPool[i] = Bytes.wrap(b);
bPool[i] = Bytes.wrap(a);
} else {
aPool[i] = Bytes.wrap(a);
bPool[i] = Bytes.wrap(b);
}
}
}
index = 0;
}

@Override
protected Operation.OperationResult invoke(final MessageFrame frame) {
return DivOperation.staticOperation(frame);
return DivOperationOptimized.staticOperation(frame);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,128 @@

import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.operation.Operation;
import org.hyperledger.besu.evm.operation.SDivOperation;
import org.hyperledger.besu.evm.operation.SDivOperationOptimized;

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

import org.apache.tuweni.bytes.Bytes;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Setup;

public class SDivOperationBenchmark extends BinaryOperationBenchmark {

public enum Case {
SDIV_32_32(1, 1),
SDIV_64_32(2, 1),
SDIV_64_64(2, 2),
SDIV_128_32(4, 1),
SDIV_128_64(4, 2),
SDIV_128_128(4, 4),
SDIV_192_32(6, 1),
SDIV_192_64(6, 2),
SDIV_192_128(6, 4),
SDIV_192_192(6, 6),
SDIV_256_32(8, 1),
SDIV_256_64(8, 2),
SDIV_256_128(8, 4),
SDIV_256_192(8, 6),
SDIV_256_256(8, 8),
SDIV_ZERO_QUOTIENT_0_256(0, 8),
SDIV_ZERO_QUOTIENT_64_256(2, 8),
SDIV_ZERO_QUOTIENT_128_256(4, 8),
SDIV_ZERO_QUOTIENT_192_256(6, 8),
SDIV_FULL_RANDOM(-1, -1);

final int numSize;
final int denomSize;

Case(final int numSize, final int denomSize) {
this.numSize = numSize;
this.denomSize = denomSize;
}
}

@Param({
"SDIV_32_32",
"SDIV_64_32",
"SDIV_64_64",
"SDIV_128_32",
"SDIV_128_64",
"SDIV_128_128",
"SDIV_192_32",
"SDIV_192_64",
"SDIV_192_128",
"SDIV_192_192",
"SDIV_256_32",
"SDIV_256_64",
"SDIV_256_128",
"SDIV_256_192",
"SDIV_256_256",
"SDIV_ZERO_QUOTIENT_0_256",
"SDIV_ZERO_QUOTIENT_64_256",
"SDIV_ZERO_QUOTIENT_128_256",
"SDIV_ZERO_QUOTIENT_192_256",
"SDIV_FULL_RANDOM"
})
private String caseName;

@Setup(Level.Iteration)
@Override
public void setUp() {
frame = BenchmarkHelper.createMessageCallFrame();

Case scenario = Case.valueOf(caseName);
aPool = new Bytes[SAMPLE_SIZE];
bPool = new Bytes[SAMPLE_SIZE];

final Random random = new Random();
int aSize;
int bSize;

for (int i = 0; i < SAMPLE_SIZE; i++) {
if (scenario.numSize < 0) aSize = random.nextInt(1, 33);
else aSize = scenario.numSize * 4;
if (scenario.denomSize < 0) bSize = random.nextInt(1, 33);
else bSize = scenario.denomSize * 4;

byte[] a = new byte[aSize];
byte[] b = new byte[bSize];
random.nextBytes(a);
random.nextBytes(b);
a = negate(a);
b = negate(b);

// Swap a and b if necessary
if ((scenario.numSize != scenario.denomSize)) {
aPool[i] = Bytes.wrap(a);
bPool[i] = Bytes.wrap(b);
} else {
BigInteger aInt = new BigInteger(a);
BigInteger bInt = new BigInteger(b);
if ((aInt.abs().compareTo(bInt.abs()) < 0)) {
aPool[i] = Bytes.wrap(b);
bPool[i] = Bytes.wrap(a);
} else {
aPool[i] = Bytes.wrap(a);
bPool[i] = Bytes.wrap(b);
}
}
}
index = 0;
}

private static byte[] negate(final byte[] array) {
byte[] tmp = new byte[32];
Arrays.fill(tmp, (byte) 0xFF);
System.arraycopy(array, 0, tmp, 32 - array.length, array.length);
return tmp;
}

@Override
protected Operation.OperationResult invoke(final MessageFrame frame) {
return SDivOperation.staticOperation(frame);
return SDivOperationOptimized.staticOperation(frame);
}
}
12 changes: 10 additions & 2 deletions evm/src/main/java/org/hyperledger/besu/evm/EVM.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.hyperledger.besu.evm.operation.ChainIdOperation;
import org.hyperledger.besu.evm.operation.CountLeadingZerosOperation;
import org.hyperledger.besu.evm.operation.DivOperation;
import org.hyperledger.besu.evm.operation.DivOperationOptimized;
import org.hyperledger.besu.evm.operation.DupNOperation;
import org.hyperledger.besu.evm.operation.DupOperation;
import org.hyperledger.besu.evm.operation.ExchangeOperation;
Expand Down Expand Up @@ -64,6 +65,7 @@
import org.hyperledger.besu.evm.operation.Push0Operation;
import org.hyperledger.besu.evm.operation.PushOperation;
import org.hyperledger.besu.evm.operation.SDivOperation;
import org.hyperledger.besu.evm.operation.SDivOperationOptimized;
import org.hyperledger.besu.evm.operation.SGtOperation;
import org.hyperledger.besu.evm.operation.SLtOperation;
import org.hyperledger.besu.evm.operation.SModOperation;
Expand Down Expand Up @@ -246,8 +248,14 @@ public void runToHalt(final MessageFrame frame, final OperationTracer tracing) {
: AddOperation.staticOperation(frame);
case 0x02 -> MulOperation.staticOperation(frame);
case 0x03 -> SubOperation.staticOperation(frame);
case 0x04 -> DivOperation.staticOperation(frame);
case 0x05 -> SDivOperation.staticOperation(frame);
case 0x04 ->
evmConfiguration.enableOptimizedOpcodes()
? DivOperationOptimized.staticOperation(frame)
: DivOperation.staticOperation(frame);
case 0x05 ->
evmConfiguration.enableOptimizedOpcodes()
? SDivOperationOptimized.staticOperation(frame)
: SDivOperation.staticOperation(frame);
case 0x06 ->
evmConfiguration.enableOptimizedOpcodes()
? ModOperationOptimized.staticOperation(frame)
Expand Down
8 changes: 6 additions & 2 deletions evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import org.hyperledger.besu.evm.operation.DelegateCallOperation;
import org.hyperledger.besu.evm.operation.DifficultyOperation;
import org.hyperledger.besu.evm.operation.DivOperation;
import org.hyperledger.besu.evm.operation.DivOperationOptimized;
import org.hyperledger.besu.evm.operation.DupNOperation;
import org.hyperledger.besu.evm.operation.DupOperation;
import org.hyperledger.besu.evm.operation.EqOperation;
Expand Down Expand Up @@ -109,6 +110,7 @@
import org.hyperledger.besu.evm.operation.ReturnOperation;
import org.hyperledger.besu.evm.operation.RevertOperation;
import org.hyperledger.besu.evm.operation.SDivOperation;
import org.hyperledger.besu.evm.operation.SDivOperationOptimized;
import org.hyperledger.besu.evm.operation.SGtOperation;
import org.hyperledger.besu.evm.operation.SLoadOperation;
import org.hyperledger.besu.evm.operation.SLtOperation;
Expand Down Expand Up @@ -205,8 +207,6 @@ private static void registerFrontierOperations(
}
registry.put(new MulOperation(gasCalculator));
registry.put(new SubOperation(gasCalculator));
registry.put(new DivOperation(gasCalculator));
registry.put(new SDivOperation(gasCalculator));
if (evmConfiguration.enableOptimizedOpcodes()) {
registry.put(new AddOperationOptimized(gasCalculator));
registry.put(new ModOperationOptimized(gasCalculator));
Expand All @@ -217,6 +217,8 @@ private static void registerFrontierOperations(
registry.put(new XorOperationOptimized(gasCalculator));
registry.put(new OrOperationOptimized(gasCalculator));
registry.put(new NotOperationOptimized(gasCalculator));
registry.put(new DivOperationOptimized(gasCalculator));
registry.put(new SDivOperationOptimized(gasCalculator));
} else {
registry.put(new AddOperation(gasCalculator));
registry.put(new ModOperation(gasCalculator));
Expand All @@ -227,6 +229,8 @@ private static void registerFrontierOperations(
registry.put(new XorOperation(gasCalculator));
registry.put(new OrOperation(gasCalculator));
registry.put(new NotOperation(gasCalculator));
registry.put(new DivOperation(gasCalculator));
registry.put(new SDivOperation(gasCalculator));
}
registry.put(new ExpOperation(gasCalculator));
registry.put(new SignExtendOperation(gasCalculator));
Expand Down
Loading
Loading