Skip to content
This repository was archived by the owner on Jul 1, 2025. It is now read-only.

Commit aec8138

Browse files
committed
implement the proposed gas changes for bls / eip-2537 (#8008)
* implement the proposed gas changes for bls / eip-2537 for pectra-devnet-5 * disable eip-2537 testing until we have new artifacts that reflect pectra gas costs Signed-off-by: garyschulte <[email protected]>
1 parent 8d2eb69 commit aec8138

File tree

28 files changed

+827
-930
lines changed

28 files changed

+827
-930
lines changed

config/src/test/java/org/hyperledger/besu/config/GenesisReaderTest.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public void readGenesisFromObjectNode() {
4141
final var configNode = mapper.createObjectNode();
4242
configNode.put("londonBlock", 1);
4343
final var allocNode = mapper.createObjectNode();
44-
allocNode.put(Address.BLS12_G2MUL.toUnprefixedHexString(), generateAllocation(Wei.ONE));
44+
allocNode.put(Address.BLS12_G2MULTIEXP.toUnprefixedHexString(), generateAllocation(Wei.ONE));
4545
final var rootNode = mapper.createObjectNode();
4646
rootNode.put("chainId", 12);
4747
rootNode.put(CONFIG_FIELD, configNode);
@@ -52,15 +52,16 @@ public void readGenesisFromObjectNode() {
5252
assertThat(genesisReader.getRoot().has(ALLOCATION_FIELD)).isFalse();
5353
assertThat(genesisReader.getConfig().get("londonblock").asInt()).isEqualTo(1);
5454
assertThat(genesisReader.streamAllocations())
55-
.containsExactly(new GenesisAccount(Address.BLS12_G2MUL, 0, Wei.ONE, null, Map.of(), null));
55+
.containsExactly(
56+
new GenesisAccount(Address.BLS12_G2MULTIEXP, 0, Wei.ONE, null, Map.of(), null));
5657
}
5758

5859
@Test
5960
public void readGenesisFromObjectDoesNotModifyObjectNodeArg() {
6061
final var configNode = mapper.createObjectNode();
6162
configNode.put("londonBlock", 1);
6263
final var allocNode = mapper.createObjectNode();
63-
allocNode.put(Address.BLS12_G2MUL.toUnprefixedHexString(), generateAllocation(Wei.ONE));
64+
allocNode.put(Address.BLS12_G2MULTIEXP.toUnprefixedHexString(), generateAllocation(Wei.ONE));
6465
final var rootNode = mapper.createObjectNode();
6566
rootNode.put("chainId", 12);
6667
rootNode.put(CONFIG_FIELD, configNode);

datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,29 +72,23 @@ public class Address extends DelegatingBytes {
7272
/** The constant BLS12_G1ADD. */
7373
public static final Address BLS12_G1ADD = Address.precompiled(0xB);
7474

75-
/** The constant BLS12_G1MUL. */
76-
public static final Address BLS12_G1MUL = Address.precompiled(0xC);
77-
7875
/** The constant BLS12_G1MULTIEXP. */
79-
public static final Address BLS12_G1MULTIEXP = Address.precompiled(0xD);
76+
public static final Address BLS12_G1MULTIEXP = Address.precompiled(0xC);
8077

8178
/** The constant BLS12_G2ADD. */
82-
public static final Address BLS12_G2ADD = Address.precompiled(0xE);
83-
84-
/** The constant BLS12_G2MUL. */
85-
public static final Address BLS12_G2MUL = Address.precompiled(0xF);
79+
public static final Address BLS12_G2ADD = Address.precompiled(0xD);
8680

8781
/** The constant BLS12_G2MULTIEXP. */
88-
public static final Address BLS12_G2MULTIEXP = Address.precompiled(0x10);
82+
public static final Address BLS12_G2MULTIEXP = Address.precompiled(0xE);
8983

9084
/** The constant BLS12_PAIRING. */
91-
public static final Address BLS12_PAIRING = Address.precompiled(0x11);
85+
public static final Address BLS12_PAIRING = Address.precompiled(0xF);
9286

9387
/** The constant BLS12_MAP_FP_TO_G1. */
94-
public static final Address BLS12_MAP_FP_TO_G1 = Address.precompiled(0x12);
88+
public static final Address BLS12_MAP_FP_TO_G1 = Address.precompiled(0x10);
9589

9690
/** The constant BLS12_MAP_FP2_TO_G2. */
97-
public static final Address BLS12_MAP_FP2_TO_G2 = Address.precompiled(0x13);
91+
public static final Address BLS12_MAP_FP2_TO_G2 = Address.precompiled(0x11);
9892

9993
/** The constant ZERO. */
10094
public static final Address ZERO = Address.fromHexString("0x0");

ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,8 @@
1717
import org.hyperledger.besu.evm.EvmSpecVersion;
1818
import org.hyperledger.besu.evm.precompile.AbstractBLS12PrecompiledContract;
1919
import org.hyperledger.besu.evm.precompile.BLS12G1AddPrecompiledContract;
20-
import org.hyperledger.besu.evm.precompile.BLS12G1MulPrecompiledContract;
2120
import org.hyperledger.besu.evm.precompile.BLS12G1MultiExpPrecompiledContract;
2221
import org.hyperledger.besu.evm.precompile.BLS12G2AddPrecompiledContract;
23-
import org.hyperledger.besu.evm.precompile.BLS12G2MulPrecompiledContract;
2422
import org.hyperledger.besu.evm.precompile.BLS12G2MultiExpPrecompiledContract;
2523
import org.hyperledger.besu.evm.precompile.BLS12MapFp2ToG2PrecompiledContract;
2624
import org.hyperledger.besu.evm.precompile.BLS12MapFpToG1PrecompiledContract;
@@ -166,11 +164,9 @@ public void runBenchmark(
166164
}
167165

168166
benchmarkG1Add(output);
169-
benchmarkG1Mul(output);
170167
benchmarkG1MultiExp32Pairs(output);
171168
benchmarkMapFpToG1(output);
172169
benchmarkG2Add(output);
173-
benchmarkG2Mul(output);
174170
benchmarkG2MultiExp32Pairs(output);
175171
benchmarkMapFp2ToG2(output);
176172
benchmarkBlsPairing(output);
@@ -198,28 +194,6 @@ private void benchmarkG1Add(final PrintStream output) {
198194
gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000);
199195
}
200196

201-
private void benchmarkG1Mul(final PrintStream output) {
202-
final Map<String, Bytes> testCases = new LinkedHashMap<>();
203-
for (int i = 0; i < g1PointPairs.length; i++) {
204-
testCases.put("G1 Mul " + i, Bytes.fromHexString(g1PointPairs[i] + scalars[i]));
205-
}
206-
207-
BLS12G1MulPrecompiledContract g1addContract = new BLS12G1MulPrecompiledContract();
208-
warmup = MATH_WARMUP / testCases.size();
209-
iterations = MATH_ITERATIONS / testCases.size();
210-
double execTime = Double.MIN_VALUE; // a way to dodge divide by zero
211-
long gasCost = 0;
212-
for (final Map.Entry<String, Bytes> testCase : testCases.entrySet()) {
213-
execTime += runPrecompileBenchmark(testCase.getValue(), g1addContract);
214-
gasCost += g1addContract.gasRequirement(testCase.getValue());
215-
}
216-
execTime /= testCases.size();
217-
gasCost /= testCases.size();
218-
output.printf(
219-
"Bls12 G1 Mul %,6d avg gas @%,7.1f µs /%,8.1f MGps%n",
220-
gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000);
221-
}
222-
223197
private void benchmarkG1MultiExp32Pairs(final PrintStream output) {
224198
final Map<String, Bytes> testCases = new LinkedHashMap<>();
225199

@@ -290,28 +264,6 @@ private void benchmarkG2Add(final PrintStream output) {
290264
gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000);
291265
}
292266

293-
private void benchmarkG2Mul(final PrintStream output) {
294-
final Map<String, Bytes> testCases = new LinkedHashMap<>();
295-
for (int i = 0; i < g2PointPairs.length; i++) {
296-
testCases.put("G2 Mul " + i, Bytes.fromHexString(g2PointPairs[i] + scalars[i]));
297-
}
298-
299-
BLS12G2MulPrecompiledContract g1addContract = new BLS12G2MulPrecompiledContract();
300-
warmup = MATH_WARMUP / testCases.size();
301-
iterations = MATH_ITERATIONS / testCases.size();
302-
double execTime = Double.MIN_VALUE; // a way to dodge divide by zero
303-
long gasCost = 0;
304-
for (final Map.Entry<String, Bytes> testCase : testCases.entrySet()) {
305-
execTime += runPrecompileBenchmark(testCase.getValue(), g1addContract);
306-
gasCost += g1addContract.gasRequirement(testCase.getValue());
307-
}
308-
execTime /= testCases.size();
309-
gasCost /= testCases.size();
310-
output.printf(
311-
"Bls12 G2 Mul %,6d avg gas @%,7.1f µs /%,8.1f MGps%n",
312-
gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000);
313-
}
314-
315267
private void benchmarkG2MultiExp32Pairs(final PrintStream output) {
316268
final Map<String, Bytes> testCases = new LinkedHashMap<>();
317269

ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/BlockchainReferenceTestTools.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ public class BlockchainReferenceTestTools {
9393

9494
// None of the Prague tests have withdrawals and deposits handling
9595
params.ignore("\\[Prague\\]");
96+
97+
// TODO: remove once updated EIP-2537 gas cost artifacts exist
98+
params.ignore("/eip2537_bls_12_381_precompiles/");
99+
params.ignore("/stEIP2537/");
96100
}
97101

98102
private BlockchainReferenceTestTools() {

ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ private static ProtocolSpec protocolSpec(final String name) {
104104

105105
// EOF tests are written against an older version of the spec
106106
params.ignore("/stEOF/");
107+
108+
// TODO: remove once updated EIP-2537 gas cost artifacts exist
109+
params.ignore("/eip2537_bls_12_381_precompiles/");
110+
params.ignore("/stEIP2537/");
111+
107112
}
108113

109114
private GeneralStateReferenceTestTools() {

evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractBLS12PrecompiledContract.java

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,40 @@ public abstract class AbstractBLS12PrecompiledContract implements PrecompiledCon
3333

3434
private static final Logger LOG = LoggerFactory.getLogger(AbstractBLS12PrecompiledContract.class);
3535

36+
static {
37+
// set parallel 1 for testing. Remove this for prod code (or set a rational limit)
38+
// LibGnarkEIP2537.setDegreeOfMSMParallelism(1);
39+
}
40+
3641
/** The Discount table. */
37-
static final int[] DISCOUNT_TABLE =
42+
static final int[] G1_DISCOUNT_TABLE =
43+
new int[] {
44+
-1, 1000, 949, 848, 797, 764, 750, 738, 728, 719, 712, 705, 698, 692, 687, 682, 677, 673,
45+
669, 665, 661, 658, 654, 651, 648, 645, 642, 640, 637, 635, 632, 630, 627, 625, 623, 621,
46+
619, 617, 615, 613, 611, 609, 608, 606, 604, 603, 601, 599, 598, 596, 595, 593, 592, 591,
47+
589, 588, 586, 585, 584, 582, 581, 580, 579, 577, 576, 575, 574, 573, 572, 570, 569, 568,
48+
567, 566, 565, 564, 563, 562, 561, 560, 559, 558, 557, 556, 555, 554, 553, 552, 551, 550,
49+
549, 548, 547, 547, 546, 545, 544, 543, 542, 541, 540, 540, 539, 538, 537, 536, 536, 535,
50+
534, 533, 532, 532, 531, 530, 529, 528, 528, 527, 526, 525, 525, 524, 523, 522, 522, 521,
51+
520, 520, 519
52+
};
53+
54+
static final int[] G2_DISCOUNT_TABLE =
3855
new int[] {
39-
-1, 1_200, 888, 764, 641, 594, 547, 500, 453, 438, 423, 408, 394, 379, 364, 349,
40-
334, 330, 326, 322, 318, 314, 310, 306, 302, 298, 294, 289, 285, 281, 277, 273,
41-
269, 268, 266, 265, 263, 262, 260, 259, 257, 256, 254, 253, 251, 250, 248, 247,
42-
245, 244, 242, 241, 239, 238, 236, 235, 233, 232, 231, 229, 228, 226, 225, 223,
43-
222, 221, 220, 219, 219, 218, 217, 216, 216, 215, 214, 213, 213, 212, 211, 211,
44-
210, 209, 208, 208, 207, 206, 205, 205, 204, 203, 202, 202, 201, 200, 199, 199,
45-
198, 197, 196, 196, 195, 194, 193, 193, 192, 191, 191, 190, 189, 188, 188, 187,
46-
186, 185, 185, 184, 183, 182, 182, 181, 180, 179, 179, 178, 177, 176, 176, 175,
47-
174
56+
-1, 1000, 1000, 923, 884, 855, 832, 812, 796, 782, 770, 759, 749, 740, 732, 724, 717, 711,
57+
704, 699, 693, 688, 683, 679, 674, 670, 666, 663, 659, 655, 652, 649, 646, 643, 640, 637,
58+
634, 632, 629, 627, 624, 622, 620, 618, 615, 613, 611, 609, 607, 606, 604, 602, 600, 598,
59+
597, 595, 593, 592, 590, 589, 587, 586, 584, 583, 582, 580, 579, 578, 576, 575, 574, 573,
60+
571, 570, 569, 568, 567, 566, 565, 563, 562, 561, 560, 559, 558, 557, 556, 555, 554, 553,
61+
552, 552, 551, 550, 549, 548, 547, 546, 545, 545, 544, 543, 542, 541, 541, 540, 539, 538,
62+
537, 537, 536, 535, 535, 534, 533, 532, 532, 531, 530, 530, 529, 528, 528, 527, 526, 526,
63+
525, 524, 524
4864
};
4965

5066
/** The Max discount. */
51-
static final int MAX_DISCOUNT = 174;
67+
static final int G1_MAX_DISCOUNT = 519;
68+
69+
static final int G2_MAX_DISCOUNT = 524;
5270

5371
private final String name;
5472
private final byte operationId;
@@ -121,21 +139,40 @@ public PrecompileContractResult computePrecompile(
121139
}
122140

123141
/**
124-
* Gets discount.
142+
* Gets G1 MSM discount.
143+
*
144+
* @param k the k
145+
* @return the discount
146+
*/
147+
protected int getG1Discount(final int k) {
148+
// `k * multiplication_cost * discount / multiplier` where `multiplier = 1000`
149+
// multiplication_cost and multiplier are folded into one constant as a long and placed first to
150+
// prevent int32 overflow
151+
// there was a table prepared for discount in case of k <= 128 points in the multiexponentiation
152+
// with a discount cup max_discount for k > 128.
153+
154+
if (k >= G1_DISCOUNT_TABLE.length) {
155+
return G1_MAX_DISCOUNT;
156+
}
157+
return G1_DISCOUNT_TABLE[k];
158+
}
159+
160+
/**
161+
* Gets G2 MSM discount.
125162
*
126163
* @param k the k
127164
* @return the discount
128165
*/
129-
protected int getDiscount(final int k) {
166+
protected int getG2Discount(final int k) {
130167
// `k * multiplication_cost * discount / multiplier` where `multiplier = 1000`
131168
// multiplication_cost and multiplier are folded into one constant as a long and placed first to
132169
// prevent int32 overflow
133170
// there was a table prepared for discount in case of k <= 128 points in the multiexponentiation
134171
// with a discount cup max_discount for k > 128.
135172

136-
if (k >= DISCOUNT_TABLE.length) {
137-
return MAX_DISCOUNT;
173+
if (k >= G2_DISCOUNT_TABLE.length) {
174+
return G2_MAX_DISCOUNT;
138175
}
139-
return DISCOUNT_TABLE[k];
176+
return G2_DISCOUNT_TABLE[k];
140177
}
141178
}

evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G1AddPrecompiledContract.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@ public BLS12G1AddPrecompiledContract() {
3030

3131
@Override
3232
public long gasRequirement(final Bytes input) {
33-
return 500L;
33+
return 375L;
3434
}
3535
}

evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G1MulPrecompiledContract.java

Lines changed: 0 additions & 35 deletions
This file was deleted.

evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G1MultiExpPrecompiledContract.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,6 @@ public BLS12G1MultiExpPrecompiledContract() {
3434
@Override
3535
public long gasRequirement(final Bytes input) {
3636
final int k = input.size() / PARAMETER_LENGTH;
37-
return 12L * k * getDiscount(k);
37+
return 12L * k * getG1Discount(k);
3838
}
3939
}

evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G2AddPrecompiledContract.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@ public BLS12G2AddPrecompiledContract() {
3030

3131
@Override
3232
public long gasRequirement(final Bytes input) {
33-
return 800L;
33+
return 600L;
3434
}
3535
}

0 commit comments

Comments
 (0)