@@ -65,7 +65,7 @@ var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{
65
65
common .BytesToAddress ([]byte {2 }): & sha256hash {},
66
66
common .BytesToAddress ([]byte {3 }): & ripemd160hash {},
67
67
common .BytesToAddress ([]byte {4 }): & dataCopy {},
68
- common .BytesToAddress ([]byte {5 }): & bigModExp {eip2565 : false , eip7823 : false },
68
+ common .BytesToAddress ([]byte {5 }): & bigModExp {eip2565 : false , eip7823 : false , eip7883 : false },
69
69
common .BytesToAddress ([]byte {6 }): & bn256AddByzantium {},
70
70
common .BytesToAddress ([]byte {7 }): & bn256ScalarMulByzantium {},
71
71
common .BytesToAddress ([]byte {8 }): & bn256PairingByzantium {},
@@ -78,7 +78,7 @@ var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContract{
78
78
common .BytesToAddress ([]byte {2 }): & sha256hash {},
79
79
common .BytesToAddress ([]byte {3 }): & ripemd160hash {},
80
80
common .BytesToAddress ([]byte {4 }): & dataCopy {},
81
- common .BytesToAddress ([]byte {5 }): & bigModExp {eip2565 : false , eip7823 : false },
81
+ common .BytesToAddress ([]byte {5 }): & bigModExp {eip2565 : false , eip7823 : false , eip7883 : false },
82
82
common .BytesToAddress ([]byte {6 }): & bn256AddIstanbul {},
83
83
common .BytesToAddress ([]byte {7 }): & bn256ScalarMulIstanbul {},
84
84
common .BytesToAddress ([]byte {8 }): & bn256PairingIstanbul {limitInputLength : false },
@@ -92,7 +92,7 @@ var PrecompiledContractsBerlin = map[common.Address]PrecompiledContract{
92
92
common .BytesToAddress ([]byte {2 }): & sha256hash {},
93
93
common .BytesToAddress ([]byte {3 }): & ripemd160hash {},
94
94
common .BytesToAddress ([]byte {4 }): & dataCopy {},
95
- common .BytesToAddress ([]byte {5 }): & bigModExp {eip2565 : true , eip7823 : false },
95
+ common .BytesToAddress ([]byte {5 }): & bigModExp {eip2565 : true , eip7823 : false , eip7883 : false },
96
96
common .BytesToAddress ([]byte {6 }): & bn256AddIstanbul {},
97
97
common .BytesToAddress ([]byte {7 }): & bn256ScalarMulIstanbul {},
98
98
common .BytesToAddress ([]byte {8 }): & bn256PairingIstanbul {limitInputLength : false },
@@ -106,7 +106,7 @@ var PrecompiledContractsArchimedes = map[common.Address]PrecompiledContract{
106
106
common .BytesToAddress ([]byte {2 }): & sha256hashDisabled {},
107
107
common .BytesToAddress ([]byte {3 }): & ripemd160hashDisabled {},
108
108
common .BytesToAddress ([]byte {4 }): & dataCopy {},
109
- common .BytesToAddress ([]byte {5 }): & bigModExp {eip2565 : true , eip7823 : false },
109
+ common .BytesToAddress ([]byte {5 }): & bigModExp {eip2565 : true , eip7823 : false , eip7883 : false },
110
110
common .BytesToAddress ([]byte {6 }): & bn256AddIstanbul {},
111
111
common .BytesToAddress ([]byte {7 }): & bn256ScalarMulIstanbul {},
112
112
common .BytesToAddress ([]byte {8 }): & bn256PairingIstanbul {limitInputLength : true },
@@ -120,7 +120,7 @@ var PrecompiledContractsBernoulli = map[common.Address]PrecompiledContract{
120
120
common .BytesToAddress ([]byte {2 }): & sha256hash {},
121
121
common .BytesToAddress ([]byte {3 }): & ripemd160hashDisabled {},
122
122
common .BytesToAddress ([]byte {4 }): & dataCopy {},
123
- common .BytesToAddress ([]byte {5 }): & bigModExp {eip2565 : true , eip7823 : false },
123
+ common .BytesToAddress ([]byte {5 }): & bigModExp {eip2565 : true , eip7823 : false , eip7883 : false },
124
124
common .BytesToAddress ([]byte {6 }): & bn256AddIstanbul {},
125
125
common .BytesToAddress ([]byte {7 }): & bn256ScalarMulIstanbul {},
126
126
common .BytesToAddress ([]byte {8 }): & bn256PairingIstanbul {limitInputLength : true },
@@ -134,7 +134,7 @@ var PrecompiledContractsEuclidV2 = map[common.Address]PrecompiledContract{
134
134
common .BytesToAddress ([]byte {2 }): & sha256hash {},
135
135
common .BytesToAddress ([]byte {3 }): & ripemd160hashDisabled {},
136
136
common .BytesToAddress ([]byte {4 }): & dataCopy {},
137
- common .BytesToAddress ([]byte {5 }): & bigModExp {eip2565 : true , eip7823 : false },
137
+ common .BytesToAddress ([]byte {5 }): & bigModExp {eip2565 : true , eip7823 : false , eip7883 : false },
138
138
common .BytesToAddress ([]byte {6 }): & bn256AddIstanbul {},
139
139
common .BytesToAddress ([]byte {7 }): & bn256ScalarMulIstanbul {},
140
140
common .BytesToAddress ([]byte {8 }): & bn256PairingIstanbul {limitInputLength : true },
@@ -149,7 +149,7 @@ var PrecompiledContractsFeynman = map[common.Address]PrecompiledContract{
149
149
common .BytesToAddress ([]byte {2 }): & sha256hash {},
150
150
common .BytesToAddress ([]byte {3 }): & ripemd160hashDisabled {},
151
151
common .BytesToAddress ([]byte {4 }): & dataCopy {},
152
- common .BytesToAddress ([]byte {5 }): & bigModExp {eip2565 : true , eip7823 : true },
152
+ common .BytesToAddress ([]byte {5 }): & bigModExp {eip2565 : true , eip7823 : true , eip7883 : true },
153
153
common .BytesToAddress ([]byte {6 }): & bn256AddIstanbul {},
154
154
common .BytesToAddress ([]byte {7 }): & bn256ScalarMulIstanbul {},
155
155
common .BytesToAddress ([]byte {8 }): & bn256PairingIstanbul {limitInputLength : false },
@@ -351,6 +351,7 @@ func (c *dataCopy) Run(in []byte) ([]byte, error) {
351
351
type bigModExp struct {
352
352
eip2565 bool
353
353
eip7823 bool
354
+ eip7883 bool
354
355
}
355
356
356
357
var (
@@ -431,40 +432,59 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 {
431
432
adjExpLen := new (big.Int )
432
433
if expLen .Cmp (big32 ) > 0 {
433
434
adjExpLen .Sub (expLen , big32 )
434
- adjExpLen .Mul (big8 , adjExpLen )
435
+ if c .eip7883 {
436
+ adjExpLen .Lsh (adjExpLen , 4 )
437
+ } else {
438
+ adjExpLen .Lsh (adjExpLen , 3 )
439
+ }
435
440
}
436
441
adjExpLen .Add (adjExpLen , big .NewInt (int64 (msb )))
437
442
// Calculate the gas cost of the operation
438
- gas := new (big.Int ).Set (math .BigMax (modLen , baseLen ))
443
+ gas := new (big.Int )
444
+ if modLen .Cmp (baseLen ) < 0 {
445
+ gas .Set (baseLen )
446
+ } else {
447
+ gas .Set (modLen )
448
+ }
449
+
450
+ maxLenOver32 := gas .Cmp (big32 ) > 0
439
451
if c .eip2565 {
440
- // EIP-2565 has three changes
452
+ // EIP-2565 (Berlin fork) has three changes:
453
+ //
441
454
// 1. Different multComplexity (inlined here)
442
455
// in EIP-2565 (https://eips.ethereum.org/EIPS/eip-2565):
443
456
//
444
457
// def mult_complexity(x):
445
458
// ceiling(x/8)^2
446
459
//
447
- //where is x is max(length_of_MODULUS, length_of_BASE)
448
- gas = gas .Add (gas , big7 )
449
- gas = gas . Div (gas , big8 )
460
+ // where is x is max(length_of_MODULUS, length_of_BASE)
461
+ gas .Add (gas , big7 )
462
+ gas . Rsh (gas , 3 )
450
463
gas .Mul (gas , gas )
451
464
452
- gas .Mul (gas , math .BigMax (adjExpLen , big1 ))
465
+ var minPrice uint64 = 200
466
+ if c .eip7883 {
467
+ minPrice = 500
468
+ if maxLenOver32 {
469
+ gas .Add (gas , gas )
470
+ }
471
+ }
472
+
473
+ if adjExpLen .Cmp (big1 ) > 0 {
474
+ gas .Mul (gas , adjExpLen )
475
+ }
453
476
// 2. Different divisor (`GQUADDIVISOR`) (3)
454
477
gas .Div (gas , big3 )
455
478
if gas .BitLen () > 64 {
456
479
return math .MaxUint64
457
480
}
458
- // 3. Minimum price of 200 gas
459
- if gas .Uint64 () < 200 {
460
- return 200
461
- }
462
- return gas .Uint64 ()
481
+ return max (minPrice , gas .Uint64 ())
463
482
}
483
+
484
+ // Pre-Berlin logic.
464
485
gas = modexpMultComplexity (gas )
465
486
gas .Mul (gas , math .BigMax (adjExpLen , big1 ))
466
487
gas .Div (gas , big20 )
467
-
468
488
if gas .BitLen () > 64 {
469
489
return math .MaxUint64
470
490
}
@@ -482,7 +502,7 @@ func (c *bigModExp) Run(input []byte) ([]byte, error) {
482
502
expLen = expLenBigInt .Uint64 ()
483
503
modLen = modLenBigInt .Uint64 ()
484
504
)
485
- if ! c .eip7823 {
505
+ if ! c .eip7823 && ! c . eip7883 {
486
506
// Check that all inputs are `u256` (32 - bytes) or less, revert otherwise
487
507
var lenLimit = new (big.Int ).SetInt64 (32 )
488
508
if baseLenBigInt .Cmp (lenLimit ) > 0 || expLenBigInt .Cmp (lenLimit ) > 0 || modLenBigInt .Cmp (lenLimit ) > 0 {
0 commit comments