@@ -4,7 +4,7 @@ import type {
4
4
EthGasPriceEstimate ,
5
5
} from '@metamask/gas-fee-controller' ;
6
6
import { GAS_ESTIMATE_TYPES } from '@metamask/gas-fee-controller' ;
7
- import { createModuleLogger , type Hex } from '@metamask/utils' ;
7
+ import { add0x , createModuleLogger , type Hex } from '@metamask/utils' ;
8
8
9
9
import { DefaultGasFeeFlow } from './DefaultGasFeeFlow' ;
10
10
import { projectLogger } from '../logger' ;
@@ -21,15 +21,21 @@ import type {
21
21
TransactionMeta ,
22
22
} from '../types' ;
23
23
import { GasFeeEstimateLevel , GasFeeEstimateType } from '../types' ;
24
- import { getRandomisedGasFeeDigits } from '../utils/feature-flags' ;
25
- import { gweiDecimalToWeiDecimal } from '../utils/gas-fees' ;
24
+ import {
25
+ getPreserveNumberOfDigitsForRandomisedGasFee ,
26
+ getRandomisedGasFeeDigits ,
27
+ } from '../utils/feature-flags' ;
28
+ import {
29
+ gweiDecimalToWeiDecimal ,
30
+ gweiDecimalToWeiHex ,
31
+ } from '../utils/gas-fees' ;
26
32
27
33
const log = createModuleLogger (
28
34
projectLogger ,
29
35
'randomised-estimation-gas-fee-flow' ,
30
36
) ;
31
37
32
- const PRESERVE_NUMBER_OF_DIGITS = 2 ;
38
+ const DEFAULT_PRESERVE_NUMBER_OF_DIGITS = 2 ;
33
39
34
40
/**
35
41
* Implementation of a gas fee flow that randomises the last digits of gas fee estimations
@@ -54,7 +60,7 @@ export class RandomisedEstimationsGasFeeFlow implements GasFeeFlow {
54
60
55
61
async getGasFees ( request : GasFeeFlowRequest ) : Promise < GasFeeFlowResponse > {
56
62
try {
57
- return await this . #getRandomisedGasFees( request ) ;
63
+ return this . #getRandomisedGasFees( request ) ;
58
64
} catch ( error ) {
59
65
log ( 'Using default flow as fallback due to error' , error ) ;
60
66
return await this . #getDefaultGasFees( request ) ;
@@ -67,9 +73,7 @@ export class RandomisedEstimationsGasFeeFlow implements GasFeeFlow {
67
73
return new DefaultGasFeeFlow ( ) . getGasFees ( request ) ;
68
74
}
69
75
70
- async #getRandomisedGasFees(
71
- request : GasFeeFlowRequest ,
72
- ) : Promise < GasFeeFlowResponse > {
76
+ #getRandomisedGasFees( request : GasFeeFlowRequest ) : GasFeeFlowResponse {
73
77
const { messenger, gasFeeControllerData, transactionMeta } = request ;
74
78
const { gasEstimateType, gasFeeEstimates } = gasFeeControllerData ;
75
79
@@ -78,29 +82,27 @@ export class RandomisedEstimationsGasFeeFlow implements GasFeeFlow {
78
82
messenger ,
79
83
) as number ;
80
84
85
+ const preservedNumberOfDigits =
86
+ getPreserveNumberOfDigitsForRandomisedGasFee ( messenger ) ;
87
+
81
88
let response : GasFeeEstimates ;
82
89
83
90
if ( gasEstimateType === GAS_ESTIMATE_TYPES . FEE_MARKET ) {
84
91
log ( 'Using fee market estimates' , gasFeeEstimates ) ;
85
- response = this . #randomiseFeeMarketEstimates (
92
+ response = this . #getRandomisedFeeMarketEstimates (
86
93
gasFeeEstimates ,
87
94
randomisedGasFeeDigits ,
95
+ preservedNumberOfDigits ,
88
96
) ;
89
- log ( 'Randomised fee market estimates' , response ) ;
97
+ log ( 'Added randomised fee market estimates' , response ) ;
90
98
} else if ( gasEstimateType === GAS_ESTIMATE_TYPES . LEGACY ) {
91
99
log ( 'Using legacy estimates' , gasFeeEstimates ) ;
92
- response = this . #randomiseLegacyEstimates(
93
- gasFeeEstimates ,
94
- randomisedGasFeeDigits ,
95
- ) ;
96
- log ( 'Randomised legacy estimates' , response ) ;
100
+ response = this . #getLegacyEstimates( gasFeeEstimates ) ;
101
+ log ( 'Added legacy estimates' , response ) ;
97
102
} else if ( gasEstimateType === GAS_ESTIMATE_TYPES . ETH_GASPRICE ) {
98
103
log ( 'Using eth_gasPrice estimates' , gasFeeEstimates ) ;
99
- response = this . #getRandomisedGasPriceEstimate(
100
- gasFeeEstimates ,
101
- randomisedGasFeeDigits ,
102
- ) ;
103
- log ( 'Randomised eth_gasPrice estimates' , response ) ;
104
+ response = this . #getGasPriceEstimates( gasFeeEstimates ) ;
105
+ log ( 'Added eth_gasPrice estimates' , response ) ;
104
106
} else {
105
107
throw new Error ( `Unsupported gas estimate type: ${ gasEstimateType } ` ) ;
106
108
}
@@ -110,9 +112,10 @@ export class RandomisedEstimationsGasFeeFlow implements GasFeeFlow {
110
112
} ;
111
113
}
112
114
113
- #randomiseFeeMarketEstimates (
115
+ #getRandomisedFeeMarketEstimates (
114
116
gasFeeEstimates : FeeMarketGasPriceEstimate ,
115
117
lastNDigits : number ,
118
+ preservedNumberOfDigits ?: number ,
116
119
) : FeeMarketGasFeeEstimates {
117
120
const levels = Object . values ( GasFeeEstimateLevel ) . reduce (
118
121
( result , level ) => ( {
@@ -121,6 +124,7 @@ export class RandomisedEstimationsGasFeeFlow implements GasFeeFlow {
121
124
gasFeeEstimates ,
122
125
level ,
123
126
lastNDigits ,
127
+ preservedNumberOfDigits ,
124
128
) ,
125
129
} ) ,
126
130
{ } as Omit < FeeMarketGasFeeEstimates , 'type' > ,
@@ -136,31 +140,28 @@ export class RandomisedEstimationsGasFeeFlow implements GasFeeFlow {
136
140
gasFeeEstimates : FeeMarketGasPriceEstimate ,
137
141
level : GasFeeEstimateLevel ,
138
142
lastNDigits : number ,
143
+ preservedNumberOfDigits ?: number ,
139
144
) : FeeMarketGasFeeEstimateForLevel {
140
145
return {
141
- maxFeePerGas : randomiseDecimalGWEIAndConvertToHex (
146
+ maxFeePerGas : gweiDecimalToWeiHex (
142
147
gasFeeEstimates [ level ] . suggestedMaxFeePerGas ,
143
- lastNDigits ,
144
148
) ,
149
+ // Only priority fee is randomised
145
150
maxPriorityFeePerGas : randomiseDecimalGWEIAndConvertToHex (
146
151
gasFeeEstimates [ level ] . suggestedMaxPriorityFeePerGas ,
147
152
lastNDigits ,
153
+ preservedNumberOfDigits ,
148
154
) ,
149
155
} ;
150
156
}
151
157
152
- #randomiseLegacyEstimates (
158
+ #getLegacyEstimates (
153
159
gasFeeEstimates : LegacyGasPriceEstimate ,
154
- lastNDigits : number ,
155
160
) : LegacyGasFeeEstimates {
156
161
const levels = Object . values ( GasFeeEstimateLevel ) . reduce (
157
162
( result , level ) => ( {
158
163
...result ,
159
- [ level ] : this . #getRandomisedLegacyLevel(
160
- gasFeeEstimates ,
161
- level ,
162
- lastNDigits ,
163
- ) ,
164
+ [ level ] : this . #getLegacyLevel( gasFeeEstimates , level ) ,
164
165
} ) ,
165
166
{ } as Omit < LegacyGasFeeEstimates , 'type' > ,
166
167
) ;
@@ -171,27 +172,19 @@ export class RandomisedEstimationsGasFeeFlow implements GasFeeFlow {
171
172
} ;
172
173
}
173
174
174
- #getRandomisedLegacyLevel (
175
+ #getLegacyLevel (
175
176
gasFeeEstimates : LegacyGasPriceEstimate ,
176
177
level : GasFeeEstimateLevel ,
177
- lastNDigits : number ,
178
178
) : Hex {
179
- return randomiseDecimalGWEIAndConvertToHex (
180
- gasFeeEstimates [ level ] ,
181
- lastNDigits ,
182
- ) ;
179
+ return gweiDecimalToWeiHex ( gasFeeEstimates [ level ] ) ;
183
180
}
184
181
185
- #getRandomisedGasPriceEstimate (
182
+ #getGasPriceEstimates (
186
183
gasFeeEstimates : EthGasPriceEstimate ,
187
- lastNDigits : number ,
188
184
) : GasPriceGasFeeEstimates {
189
185
return {
190
186
type : GasFeeEstimateType . GasPrice ,
191
- gasPrice : randomiseDecimalGWEIAndConvertToHex (
192
- gasFeeEstimates . gasPrice ,
193
- lastNDigits ,
194
- ) ,
187
+ gasPrice : gweiDecimalToWeiHex ( gasFeeEstimates . gasPrice ) ,
195
188
} ;
196
189
}
197
190
}
@@ -216,20 +209,25 @@ function generateRandomDigits(digitCount: number, minValue: number): number {
216
209
* The randomisation is performed in Wei units for more precision.
217
210
*
218
211
* @param gweiDecimalValue - The original gas fee value in Gwei (decimal)
219
- * @param [numberOfDigitsToRandomizeAtTheEnd] - The number of least significant digits to randomise
212
+ * @param numberOfDigitsToRandomizeAtTheEnd - The number of least significant digits to randomise
213
+ * @param preservedNumberOfDigits - The number of most significant digits to preserve
220
214
* @returns The randomised value converted to Wei in hexadecimal format
221
215
*/
222
216
export function randomiseDecimalGWEIAndConvertToHex (
223
217
gweiDecimalValue : string | number ,
224
218
numberOfDigitsToRandomizeAtTheEnd : number ,
219
+ preservedNumberOfDigits ?: number ,
225
220
) : Hex {
226
221
const weiDecimalValue = gweiDecimalToWeiDecimal ( gweiDecimalValue ) ;
227
222
const decimalLength = weiDecimalValue . length ;
228
223
224
+ const preservedDigits =
225
+ preservedNumberOfDigits ?? DEFAULT_PRESERVE_NUMBER_OF_DIGITS ;
226
+
229
227
// Determine how many digits to randomise while preserving the PRESERVE_NUMBER_OF_DIGITS
230
228
const effectiveDigitsToRandomise = Math . min (
231
229
numberOfDigitsToRandomizeAtTheEnd ,
232
- decimalLength - PRESERVE_NUMBER_OF_DIGITS ,
230
+ decimalLength - preservedDigits ,
233
231
) ;
234
232
235
233
// Handle the case when the value is 0 or too small
@@ -256,5 +254,7 @@ export function randomiseDecimalGWEIAndConvertToHex(
256
254
) ;
257
255
const randomisedWeiDecimal = basePart + BigInt ( randomEndingDigits ) ;
258
256
259
- return `0x${ randomisedWeiDecimal . toString ( 16 ) } ` as Hex ;
257
+ const hexRandomisedWei = `0x${ randomisedWeiDecimal . toString ( 16 ) } ` ;
258
+
259
+ return add0x ( hexRandomisedWei ) ;
260
260
}
0 commit comments