Skip to content

Commit 35dd84c

Browse files
jwasingerMariusVanDerWijdenfjl
authored
core/vm: implement EIP 7883 - ModExp Gas Cost Increase (#31606)
https://eips.ethereum.org/EIPS/eip-7883 --------- Co-authored-by: MariusVanDerWijden <m.vanderwijden@live.de> Co-authored-by: Felix Lange <fjl@twurst.com>
1 parent 0007f62 commit 35dd84c

File tree

3 files changed

+147
-17
lines changed

3 files changed

+147
-17
lines changed

core/vm/contracts.go

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ var PrecompiledContractsByzantium = PrecompiledContracts{
6666
common.BytesToAddress([]byte{0x2}): &sha256hash{},
6767
common.BytesToAddress([]byte{0x3}): &ripemd160hash{},
6868
common.BytesToAddress([]byte{0x4}): &dataCopy{},
69-
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: false, eip7823: false},
69+
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: false, eip7823: false, eip7883: false},
7070
common.BytesToAddress([]byte{0x6}): &bn256AddByzantium{},
7171
common.BytesToAddress([]byte{0x7}): &bn256ScalarMulByzantium{},
7272
common.BytesToAddress([]byte{0x8}): &bn256PairingByzantium{},
@@ -79,7 +79,7 @@ var PrecompiledContractsIstanbul = PrecompiledContracts{
7979
common.BytesToAddress([]byte{0x2}): &sha256hash{},
8080
common.BytesToAddress([]byte{0x3}): &ripemd160hash{},
8181
common.BytesToAddress([]byte{0x4}): &dataCopy{},
82-
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: false, eip7823: false},
82+
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: false, eip7823: false, eip7883: false},
8383
common.BytesToAddress([]byte{0x6}): &bn256AddIstanbul{},
8484
common.BytesToAddress([]byte{0x7}): &bn256ScalarMulIstanbul{},
8585
common.BytesToAddress([]byte{0x8}): &bn256PairingIstanbul{},
@@ -93,7 +93,7 @@ var PrecompiledContractsBerlin = PrecompiledContracts{
9393
common.BytesToAddress([]byte{0x2}): &sha256hash{},
9494
common.BytesToAddress([]byte{0x3}): &ripemd160hash{},
9595
common.BytesToAddress([]byte{0x4}): &dataCopy{},
96-
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: true, eip7823: false},
96+
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: true, eip7823: false, eip7883: false},
9797
common.BytesToAddress([]byte{0x6}): &bn256AddIstanbul{},
9898
common.BytesToAddress([]byte{0x7}): &bn256ScalarMulIstanbul{},
9999
common.BytesToAddress([]byte{0x8}): &bn256PairingIstanbul{},
@@ -107,7 +107,7 @@ var PrecompiledContractsCancun = PrecompiledContracts{
107107
common.BytesToAddress([]byte{0x2}): &sha256hash{},
108108
common.BytesToAddress([]byte{0x3}): &ripemd160hash{},
109109
common.BytesToAddress([]byte{0x4}): &dataCopy{},
110-
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: true, eip7823: false},
110+
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: true, eip7823: false, eip7883: false},
111111
common.BytesToAddress([]byte{0x6}): &bn256AddIstanbul{},
112112
common.BytesToAddress([]byte{0x7}): &bn256ScalarMulIstanbul{},
113113
common.BytesToAddress([]byte{0x8}): &bn256PairingIstanbul{},
@@ -122,7 +122,7 @@ var PrecompiledContractsPrague = PrecompiledContracts{
122122
common.BytesToAddress([]byte{0x02}): &sha256hash{},
123123
common.BytesToAddress([]byte{0x03}): &ripemd160hash{},
124124
common.BytesToAddress([]byte{0x04}): &dataCopy{},
125-
common.BytesToAddress([]byte{0x05}): &bigModExp{eip2565: true, eip7823: false},
125+
common.BytesToAddress([]byte{0x05}): &bigModExp{eip2565: true, eip7823: false, eip7883: false},
126126
common.BytesToAddress([]byte{0x06}): &bn256AddIstanbul{},
127127
common.BytesToAddress([]byte{0x07}): &bn256ScalarMulIstanbul{},
128128
common.BytesToAddress([]byte{0x08}): &bn256PairingIstanbul{},
@@ -148,7 +148,7 @@ var PrecompiledContractsOsaka = PrecompiledContracts{
148148
common.BytesToAddress([]byte{0x02}): &sha256hash{},
149149
common.BytesToAddress([]byte{0x03}): &ripemd160hash{},
150150
common.BytesToAddress([]byte{0x04}): &dataCopy{},
151-
common.BytesToAddress([]byte{0x05}): &bigModExp{eip2565: true, eip7823: true},
151+
common.BytesToAddress([]byte{0x05}): &bigModExp{eip2565: true, eip7823: true, eip7883: true},
152152
common.BytesToAddress([]byte{0x06}): &bn256AddIstanbul{},
153153
common.BytesToAddress([]byte{0x07}): &bn256ScalarMulIstanbul{},
154154
common.BytesToAddress([]byte{0x08}): &bn256PairingIstanbul{},
@@ -164,6 +164,7 @@ var PrecompiledContractsOsaka = PrecompiledContracts{
164164
}
165165

166166
var (
167+
PrecompiledAddressesOsaka []common.Address
167168
PrecompiledAddressesPrague []common.Address
168169
PrecompiledAddressesCancun []common.Address
169170
PrecompiledAddressesBerlin []common.Address
@@ -191,6 +192,9 @@ func init() {
191192
for k := range PrecompiledContractsPrague {
192193
PrecompiledAddressesPrague = append(PrecompiledAddressesPrague, k)
193194
}
195+
for k := range PrecompiledContractsOsaka {
196+
PrecompiledAddressesOsaka = append(PrecompiledAddressesOsaka, k)
197+
}
194198
}
195199

196200
func activePrecompiledContracts(rules params.Rules) PrecompiledContracts {
@@ -222,6 +226,8 @@ func ActivePrecompiledContracts(rules params.Rules) PrecompiledContracts {
222226
// ActivePrecompiles returns the precompile addresses enabled with the current configuration.
223227
func ActivePrecompiles(rules params.Rules) []common.Address {
224228
switch {
229+
case rules.IsOsaka:
230+
return PrecompiledAddressesOsaka
225231
case rules.IsPrague:
226232
return PrecompiledAddressesPrague
227233
case rules.IsCancun:
@@ -342,6 +348,7 @@ func (c *dataCopy) Run(in []byte) ([]byte, error) {
342348
type bigModExp struct {
343349
eip2565 bool
344350
eip7823 bool
351+
eip7883 bool
345352
}
346353

347354
var (
@@ -417,7 +424,11 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 {
417424
adjExpLen := new(big.Int)
418425
if expLen.Cmp(big32) > 0 {
419426
adjExpLen.Sub(expLen, big32)
420-
adjExpLen.Lsh(adjExpLen, 3)
427+
if c.eip7883 {
428+
adjExpLen.Lsh(adjExpLen, 4)
429+
} else {
430+
adjExpLen.Lsh(adjExpLen, 3)
431+
}
421432
}
422433
adjExpLen.Add(adjExpLen, big.NewInt(int64(msb)))
423434
// Calculate the gas cost of the operation
@@ -427,19 +438,30 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 {
427438
} else {
428439
gas.Set(modLen)
429440
}
441+
442+
maxLenOver32 := gas.Cmp(big32) > 0
430443
if c.eip2565 {
431-
// EIP-2565 has three changes
444+
// EIP-2565 (Berlin fork) has three changes:
445+
//
432446
// 1. Different multComplexity (inlined here)
433447
// in EIP-2565 (https://eips.ethereum.org/EIPS/eip-2565):
434448
//
435449
// def mult_complexity(x):
436450
// ceiling(x/8)^2
437451
//
438-
//where is x is max(length_of_MODULUS, length_of_BASE)
452+
// where is x is max(length_of_MODULUS, length_of_BASE)
439453
gas.Add(gas, big7)
440454
gas.Rsh(gas, 3)
441455
gas.Mul(gas, gas)
442456

457+
var minPrice uint64 = 200
458+
if c.eip7883 {
459+
minPrice = 500
460+
if maxLenOver32 {
461+
gas.Add(gas, gas)
462+
}
463+
}
464+
443465
if adjExpLen.Cmp(big1) > 0 {
444466
gas.Mul(gas, adjExpLen)
445467
}
@@ -448,18 +470,15 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 {
448470
if gas.BitLen() > 64 {
449471
return math.MaxUint64
450472
}
451-
// 3. Minimum price of 200 gas
452-
if gas.Uint64() < 200 {
453-
return 200
454-
}
455-
return gas.Uint64()
473+
return max(minPrice, gas.Uint64())
456474
}
475+
476+
// Pre-Berlin logic.
457477
gas = modexpMultComplexity(gas)
458478
if adjExpLen.Cmp(big1) > 0 {
459479
gas.Mul(gas, adjExpLen)
460480
}
461481
gas.Div(gas, big20)
462-
463482
if gas.BitLen() > 64 {
464483
return math.MaxUint64
465484
}

core/vm/contracts_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ var allPrecompiles = map[common.Address]PrecompiledContract{
5050
common.BytesToAddress([]byte{2}): &sha256hash{},
5151
common.BytesToAddress([]byte{3}): &ripemd160hash{},
5252
common.BytesToAddress([]byte{4}): &dataCopy{},
53-
common.BytesToAddress([]byte{5}): &bigModExp{eip2565: false},
54-
common.BytesToAddress([]byte{0xf5}): &bigModExp{eip2565: true},
53+
common.BytesToAddress([]byte{5}): &bigModExp{eip2565: false, eip7883: false},
54+
common.BytesToAddress([]byte{0xf5}): &bigModExp{eip2565: true, eip7883: false},
55+
common.BytesToAddress([]byte{0xf6}): &bigModExp{eip2565: true, eip7883: true},
5556
common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
5657
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
5758
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
@@ -238,6 +239,9 @@ func BenchmarkPrecompiledModExp(b *testing.B) { benchJson("modexp", "05", b) }
238239
func TestPrecompiledModExpEip2565(t *testing.T) { testJson("modexp_eip2565", "f5", t) }
239240
func BenchmarkPrecompiledModExpEip2565(b *testing.B) { benchJson("modexp_eip2565", "f5", b) }
240241

242+
func TestPrecompiledModExpEip7883(t *testing.T) { testJson("modexp_eip7883", "f6", t) }
243+
func BenchmarkPrecompiledModExpEip7883(b *testing.B) { benchJson("modexp_eip7883", "f6", b) }
244+
241245
// Tests the sample inputs from the elliptic curve addition EIP 213.
242246
func TestPrecompiledBn256Add(t *testing.T) { testJson("bn256Add", "06", t) }
243247
func BenchmarkPrecompiledBn256Add(b *testing.B) { benchJson("bn256Add", "06", b) }

0 commit comments

Comments
 (0)