1
1
from typing import (
2
+ Callable ,
2
3
Tuple ,
3
4
)
4
5
5
6
from eth_utils import (
6
7
big_endian_to_int ,
7
8
int_to_big_endian ,
8
9
)
10
+ from eth_utils .toolz import (
11
+ curry ,
12
+ )
9
13
10
14
from eth import constants
11
15
23
27
)
24
28
25
29
26
- def _compute_adjusted_exponent_length (exponent_length : int ,
27
- first_32_exponent_bytes : bytes ) -> int :
30
+ def compute_adjusted_exponent_length (exponent_length : int ,
31
+ first_32_exponent_bytes : bytes ) -> int :
28
32
exponent = big_endian_to_int (first_32_exponent_bytes )
29
33
30
34
if exponent_length <= 32 and exponent == 0 :
@@ -50,7 +54,7 @@ def _compute_complexity(length: int) -> int:
50
54
return length ** 2 // 16 + 480 * length - 199680
51
55
52
56
53
- def _extract_lengths (data : bytes ) -> Tuple [int , int , int ]:
57
+ def extract_lengths (data : bytes ) -> Tuple [int , int , int ]:
54
58
# extract argument lengths
55
59
base_length_bytes = pad32r (data [:32 ])
56
60
base_length = big_endian_to_int (base_length_bytes )
@@ -64,14 +68,14 @@ def _extract_lengths(data: bytes) -> Tuple[int, int, int]:
64
68
return base_length , exponent_length , modulus_length
65
69
66
70
67
- def _compute_modexp_gas_fee (data : bytes ) -> int :
68
- base_length , exponent_length , modulus_length = _extract_lengths (data )
71
+ def _compute_modexp_gas_fee_eip_198 (data : bytes ) -> int :
72
+ base_length , exponent_length , modulus_length = extract_lengths (data )
69
73
70
74
first_32_exponent_bytes = zpad_right (
71
75
data [96 + base_length :96 + base_length + exponent_length ],
72
76
to_size = min (exponent_length , 32 ),
73
77
)[:32 ]
74
- adjusted_exponent_length = _compute_adjusted_exponent_length (
78
+ adjusted_exponent_length = compute_adjusted_exponent_length (
75
79
exponent_length ,
76
80
first_32_exponent_bytes ,
77
81
)
@@ -86,7 +90,7 @@ def _compute_modexp_gas_fee(data: bytes) -> int:
86
90
87
91
88
92
def _modexp (data : bytes ) -> int :
89
- base_length , exponent_length , modulus_length = _extract_lengths (data )
93
+ base_length , exponent_length , modulus_length = extract_lengths (data )
90
94
91
95
if base_length == 0 :
92
96
return 0
@@ -121,18 +125,22 @@ def _modexp(data: bytes) -> int:
121
125
return result
122
126
123
127
124
- def modexp (computation : BaseComputation ) -> BaseComputation :
128
+ @curry
129
+ def modexp (
130
+ computation : BaseComputation ,
131
+ gas_calculator : Callable [[bytes ], int ] = _compute_modexp_gas_fee_eip_198
132
+ ) -> BaseComputation :
125
133
"""
126
134
https://github.com/ethereum/EIPs/pull/198
127
135
"""
128
136
data = computation .msg .data_as_bytes
129
137
130
- gas_fee = _compute_modexp_gas_fee (data )
138
+ gas_fee = gas_calculator (data )
131
139
computation .consume_gas (gas_fee , reason = 'MODEXP Precompile' )
132
140
133
141
result = _modexp (data )
134
142
135
- _ , _ , modulus_length = _extract_lengths (data )
143
+ _ , _ , modulus_length = extract_lengths (data )
136
144
137
145
# Modulo 0 is undefined, return zero
138
146
# https://math.stackexchange.com/questions/516251/why-is-n-mod-0-undefined
0 commit comments