@@ -6,13 +6,9 @@ package gas
66import (
77 "math"
88
9- "github.com/holiman/uint256"
10-
119 safemath "github.com/ava-labs/avalanchego/utils/math"
1210)
1311
14- var maxUint64 = new (uint256.Int ).SetUint64 (math .MaxUint64 )
15-
1612type (
1713 Gas uint64
1814 Price uint64
@@ -57,65 +53,10 @@ func (g Gas) SubOverTime(gasRate Gas, duration uint64) Gas {
5753
5854// CalculatePrice returns the gas price given the minimum gas price, the
5955// excess gas, and the excess conversion constant.
60- //
61- // It is defined as an approximation of:
62- //
63- // minPrice * e^(excess / excessConversionConstant)
64- //
65- // This implements the EIP-4844 fake exponential formula:
66- //
67- // def fake_exponential(factor: int, numerator: int, denominator: int) -> int:
68- // i = 1
69- // output = 0
70- // numerator_accum = factor * denominator
71- // while numerator_accum > 0:
72- // output += numerator_accum
73- // numerator_accum = (numerator_accum * numerator) // (denominator * i)
74- // i += 1
75- // return output // denominator
76- //
77- // This implementation is optimized with the knowledge that any value greater
78- // than MaxUint64 gets returned as MaxUint64. This means that every intermediate
79- // value is guaranteed to be at most MaxUint193. So, we can safely use
80- // uint256.Int.
81- //
82- // This function does not perform any memory allocations.
83- //
84- //nolint:dupword // The python is copied from the EIP-4844 specification
8556func CalculatePrice (
8657 minPrice Price ,
8758 excess Gas ,
8859 excessConversionConstant Gas ,
8960) Price {
90- var (
91- numerator uint256.Int
92- denominator uint256.Int
93-
94- i uint256.Int
95- output uint256.Int
96- numeratorAccum uint256.Int
97-
98- maxOutput uint256.Int
99- )
100- numerator .SetUint64 (uint64 (excess )) // range is [0, MaxUint64]
101- denominator .SetUint64 (uint64 (excessConversionConstant )) // range is [0, MaxUint64]
102-
103- i .SetOne ()
104- numeratorAccum .SetUint64 (uint64 (minPrice )) // range is [0, MaxUint64]
105- numeratorAccum .Mul (& numeratorAccum , & denominator ) // range is [0, MaxUint128]
106-
107- maxOutput .Mul (& denominator , maxUint64 ) // range is [0, MaxUint128]
108- for numeratorAccum .Sign () > 0 {
109- output .Add (& output , & numeratorAccum ) // range is [0, MaxUint192+MaxUint128]
110- if output .Cmp (& maxOutput ) >= 0 {
111- return math .MaxUint64
112- }
113- // maxOutput < MaxUint128 so numeratorAccum < MaxUint128.
114- numeratorAccum .Mul (& numeratorAccum , & numerator ) // range is [0, MaxUint192]
115- numeratorAccum .Div (& numeratorAccum , & denominator )
116- numeratorAccum .Div (& numeratorAccum , & i )
117-
118- i .AddUint64 (& i , 1 )
119- }
120- return Price (output .Div (& output , & denominator ).Uint64 ())
61+ return Price (safemath .CalculateExponential (uint64 (minPrice ), uint64 (excess ), uint64 (excessConversionConstant )))
12162}
0 commit comments