@aztec/ethereum 2.1.9-rc.1 → 2.1.9-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/l1_tx_utils/config.d.ts +2 -2
- package/dest/l1_tx_utils/config.d.ts.map +1 -1
- package/dest/l1_tx_utils/config.js +17 -3
- package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -1
- package/dest/l1_tx_utils/readonly_l1_tx_utils.js +38 -37
- package/package.json +5 -5
- package/src/l1_tx_utils/config.ts +24 -6
- package/src/l1_tx_utils/readonly_l1_tx_utils.ts +48 -49
|
@@ -21,9 +21,9 @@ export interface L1TxUtilsConfig {
|
|
|
21
21
|
*/
|
|
22
22
|
priorityFeeRetryBumpPercentage?: number;
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
24
|
+
* Minimum priority fee per gas in Gwei. Acts as a floor for the computed priority fee.
|
|
25
25
|
*/
|
|
26
|
-
|
|
26
|
+
minimumPriorityFeePerGas?: number;
|
|
27
27
|
/**
|
|
28
28
|
* Maximum number of speed-up attempts
|
|
29
29
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/l1_tx_utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EAMxB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC;;OAEG;IACH,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC;;OAEG;IACH,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/l1_tx_utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EAMxB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC;;OAEG;IACH,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC;;OAEG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;OAEG;IACH,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC;;OAEG;IACH,2BAA2B,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,eAAO,MAAM,uBAAuB,EAAE,kBAAkB,CAAC,eAAe,CAgFvE,CAAC;AAGF,eAAO,MAAM,sBAAsB,EAE9B,QAAQ,CAAC,eAAe,CAAC,CAAC;AAE/B,wBAAgB,yBAAyB,IAAI,eAAe,CAE3D"}
|
|
@@ -31,12 +31,23 @@ export const l1TxUtilsConfigMappings = {
|
|
|
31
31
|
env: 'L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE',
|
|
32
32
|
...numberConfigHelper(50)
|
|
33
33
|
},
|
|
34
|
-
|
|
35
|
-
description: '
|
|
36
|
-
env: '
|
|
34
|
+
minimumPriorityFeePerGas: {
|
|
35
|
+
description: 'Minimum priority fee per gas in Gwei. Acts as a floor for the computed priority fee. If network conditions require a higher fee, the higher fee will be used.',
|
|
36
|
+
env: 'L1_MINIMUM_PRIORITY_FEE_PER_GAS_GWEI',
|
|
37
37
|
fallback: [
|
|
38
|
+
'L1_FIXED_PRIORITY_FEE_PER_GAS',
|
|
38
39
|
'L1_FIXED_PRIORITY_FEE_PER_GAS_GWEI'
|
|
39
40
|
],
|
|
41
|
+
deprecatedFallback: [
|
|
42
|
+
{
|
|
43
|
+
env: 'L1_FIXED_PRIORITY_FEE_PER_GAS',
|
|
44
|
+
message: deprecatedFixedFeeMessage('L1_FIXED_PRIORITY_FEE_PER_GAS')
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
env: 'L1_FIXED_PRIORITY_FEE_PER_GAS_GWEI',
|
|
48
|
+
message: deprecatedFixedFeeMessage('L1_FIXED_PRIORITY_FEE_PER_GAS_GWEI')
|
|
49
|
+
}
|
|
50
|
+
],
|
|
40
51
|
...floatConfigHelper(0)
|
|
41
52
|
},
|
|
42
53
|
maxSpeedUpAttempts: {
|
|
@@ -80,3 +91,6 @@ export const defaultL1TxUtilsConfig = getDefaultConfig(l1TxUtilsConfigMappings);
|
|
|
80
91
|
export function getL1TxUtilsConfigEnvVars() {
|
|
81
92
|
return getConfigFromMappings(l1TxUtilsConfigMappings);
|
|
82
93
|
}
|
|
94
|
+
function deprecatedFixedFeeMessage(envVar) {
|
|
95
|
+
return `Environment variable ${envVar} is deprecated. It is now used as a MINIMUM priority fee rather than a fixed value. ` + 'Please use L1_MINIMUM_PRIORITY_FEE_PER_GAS_GWEI instead. If network conditions require a higher fee, the higher fee will be used.';
|
|
96
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readonly_l1_tx_utils.d.ts","sourceRoot":"","sources":["../../src/l1_tx_utils/readonly_l1_tx_utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAElE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAIvD,OAAO,EACL,KAAK,GAAG,EACR,KAAK,OAAO,EAEZ,KAAK,cAAc,EAEnB,KAAK,GAAG,EAGR,KAAK,aAAa,EAKnB,MAAM,MAAM,CAAC;AAEd,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,KAAK,eAAe,EAAmD,MAAM,aAAa,CAAC;AAQpG,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAKxF,qBAAa,iBAAiB;IAKnB,MAAM,EAAE,UAAU;IACzB,SAAS,CAAC,MAAM,EAAE,MAAM;aACR,YAAY,EAAE,YAAY;IAE1C,SAAS,CAAC,gBAAgB,EAAE,OAAO;IAR9B,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;IACzC,SAAS,CAAC,WAAW,UAAS;gBAGrB,MAAM,EAAE,UAAU,EACf,MAAM,EAAE,MAAM,YAA6C,EACrD,YAAY,EAAE,YAAY,EAC1C,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,EACvB,gBAAgB,GAAE,OAAe;IAKtC,SAAS;IAIT,OAAO;IAIP,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAIR,cAAc;IAIrB;;;;;;;OAOG;IACH,SAAS,CAAC,yBAAyB,CACjC,qBAAqB,EAAE,oBAAoB,CAAC,MAAM,GAAG,IAAI,CAAC,EAC1D,kBAAkB,EAAE,oBAAoB,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAC5F,gBAAgB,EAAE,oBAAoB,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAC9F,MAAM;IA0GT;;OAEG;IACU,WAAW,CACtB,kBAAkB,CAAC,EAAE,eAAe,EACpC,QAAQ,GAAE,OAAe,EACzB,OAAO,GAAE,MAAU,EACnB,gBAAgB,CAAC,EAAE,OAAO,OAAO,SAAS,CAAC,GAAG,KAAK,GAAG,QAAQ,GAC7D,OAAO,CAAC,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"readonly_l1_tx_utils.d.ts","sourceRoot":"","sources":["../../src/l1_tx_utils/readonly_l1_tx_utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -131,12 +131,12 @@ export class ReadOnlyL1TxUtils {
|
|
|
131
131
|
const latestBlockPromise = this.tryTwice(()=>this.client.getBlock({
|
|
132
132
|
blockTag: 'latest'
|
|
133
133
|
}), 'Getting latest block');
|
|
134
|
-
const networkEstimatePromise =
|
|
135
|
-
const pendingBlockPromise =
|
|
134
|
+
const networkEstimatePromise = this.tryTwice(()=>this.client.estimateMaxPriorityFeePerGas(), 'Estimating max priority fee per gas');
|
|
135
|
+
const pendingBlockPromise = this.tryTwice(()=>this.client.getBlock({
|
|
136
136
|
blockTag: 'pending',
|
|
137
137
|
includeTransactions: true
|
|
138
138
|
}), 'Getting pending block');
|
|
139
|
-
const feeHistoryPromise =
|
|
139
|
+
const feeHistoryPromise = this.tryTwice(()=>this.client.getFeeHistory({
|
|
140
140
|
blockCount: HISTORICAL_BLOCK_COUNT,
|
|
141
141
|
rewardPercentiles: [
|
|
142
142
|
75
|
|
@@ -145,9 +145,9 @@ export class ReadOnlyL1TxUtils {
|
|
|
145
145
|
const blobBaseFeePromise = isBlobTx ? this.tryTwice(()=>this.client.getBlobBaseFee(), 'Getting blob base fee') : null;
|
|
146
146
|
const [latestBlockResult, networkEstimateResult, pendingBlockResult, feeHistoryResult, blobBaseFeeResult] = await Promise.allSettled([
|
|
147
147
|
latestBlockPromise,
|
|
148
|
-
networkEstimatePromise
|
|
149
|
-
pendingBlockPromise
|
|
150
|
-
feeHistoryPromise
|
|
148
|
+
networkEstimatePromise,
|
|
149
|
+
pendingBlockPromise,
|
|
150
|
+
feeHistoryPromise,
|
|
151
151
|
blobBaseFeePromise ?? Promise.resolve(0n)
|
|
152
152
|
]);
|
|
153
153
|
// Extract results
|
|
@@ -159,15 +159,23 @@ export class ReadOnlyL1TxUtils {
|
|
|
159
159
|
} else if (isBlobTx) {
|
|
160
160
|
this.logger?.warn('Failed to get L1 blob base fee', attempt);
|
|
161
161
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
162
|
+
// Get competitive priority fee
|
|
163
|
+
let priorityFee = this.getCompetitivePriorityFee(networkEstimateResult, pendingBlockResult, feeHistoryResult);
|
|
164
|
+
// Apply minimum priority fee as a floor if configured
|
|
165
|
+
if (gasConfig.minimumPriorityFeePerGas) {
|
|
166
|
+
const minimumFee = BigInt(Math.trunc(gasConfig.minimumPriorityFeePerGas * Number(WEI_CONST)));
|
|
167
|
+
if (minimumFee > priorityFee) {
|
|
168
|
+
this.logger?.debug('Using minimum priority fee as floor', {
|
|
169
|
+
minimumPriorityFeePerGas: formatGwei(minimumFee),
|
|
170
|
+
competitiveFee: formatGwei(priorityFee)
|
|
171
|
+
});
|
|
172
|
+
priorityFee = minimumFee;
|
|
173
|
+
} else {
|
|
174
|
+
this.logger?.debug('Competitive fee exceeds minimum, using competitive fee', {
|
|
175
|
+
minimumPriorityFeePerGas: formatGwei(minimumFee),
|
|
176
|
+
competitiveFee: formatGwei(priorityFee)
|
|
177
|
+
});
|
|
178
|
+
}
|
|
171
179
|
}
|
|
172
180
|
let maxFeePerGas = baseFee;
|
|
173
181
|
let maxFeePerBlobGas = blobBaseFee;
|
|
@@ -188,17 +196,14 @@ export class ReadOnlyL1TxUtils {
|
|
|
188
196
|
// multiply by 100 & divide by 100 to maintain some precision
|
|
189
197
|
const minPriorityFee = previousGasPrice.maxPriorityFeePerGas * (100_00n + BigInt(bumpPercentage * 1_00)) / 100_00n;
|
|
190
198
|
const minMaxFee = previousGasPrice.maxFeePerGas * (100_00n + BigInt(bumpPercentage * 1_00)) / 100_00n;
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
bumpPercentage: configBump
|
|
200
|
-
});
|
|
201
|
-
}
|
|
199
|
+
// Apply bump percentage to competitive fee
|
|
200
|
+
const competitivePriorityFee = priorityFee * (100_00n + BigInt(configBump * 1_00)) / 100_00n;
|
|
201
|
+
this.logger?.debug(`Speed-up attempt ${attempt}: using competitive fee strategy`, {
|
|
202
|
+
networkEstimate: formatGwei(priorityFee),
|
|
203
|
+
competitiveFee: formatGwei(competitivePriorityFee),
|
|
204
|
+
minRequired: formatGwei(minPriorityFee),
|
|
205
|
+
bumpPercentage: configBump
|
|
206
|
+
});
|
|
202
207
|
// Use maximum between competitive fee and minimum required bump
|
|
203
208
|
const finalPriorityFee = competitivePriorityFee > minPriorityFee ? competitivePriorityFee : minPriorityFee;
|
|
204
209
|
const feeSource = finalPriorityFee === competitivePriorityFee ? 'competitive' : 'minimum-bump';
|
|
@@ -206,20 +211,16 @@ export class ReadOnlyL1TxUtils {
|
|
|
206
211
|
// Add the final priority fee to maxFeePerGas
|
|
207
212
|
maxFeePerGas += finalPriorityFee;
|
|
208
213
|
maxFeePerGas = maxFeePerGas > minMaxFee ? maxFeePerGas : minMaxFee;
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
+
this.logger?.debug(`Speed-up fee decision: using ${feeSource} fee`, {
|
|
215
|
+
finalPriorityFee: formatGwei(finalPriorityFee)
|
|
216
|
+
});
|
|
214
217
|
} else {
|
|
215
218
|
// First attempt: apply configured bump percentage to competitive fee
|
|
216
219
|
// multiply by 100 & divide by 100 to maintain some precision
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
});
|
|
222
|
-
}
|
|
220
|
+
priorityFee = priorityFee * (100_00n + BigInt((gasConfig.priorityFeeBumpPercentage || 0) * 1_00)) / 100_00n;
|
|
221
|
+
this.logger?.debug('Initial transaction: using competitive fee from market analysis', {
|
|
222
|
+
networkEstimate: formatGwei(priorityFee)
|
|
223
|
+
});
|
|
223
224
|
maxFeePerGas += priorityFee;
|
|
224
225
|
}
|
|
225
226
|
// maxGwei and maxBlobGwei are hard limits
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/ethereum",
|
|
3
|
-
"version": "2.1.9-rc.
|
|
3
|
+
"version": "2.1.9-rc.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"../package.common.json"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@aztec/blob-lib": "2.1.9-rc.
|
|
35
|
-
"@aztec/constants": "2.1.9-rc.
|
|
36
|
-
"@aztec/foundation": "2.1.9-rc.
|
|
37
|
-
"@aztec/l1-artifacts": "2.1.9-rc.
|
|
34
|
+
"@aztec/blob-lib": "2.1.9-rc.3",
|
|
35
|
+
"@aztec/constants": "2.1.9-rc.3",
|
|
36
|
+
"@aztec/foundation": "2.1.9-rc.3",
|
|
37
|
+
"@aztec/l1-artifacts": "2.1.9-rc.3",
|
|
38
38
|
"@viem/anvil": "^0.0.10",
|
|
39
39
|
"dotenv": "^16.0.3",
|
|
40
40
|
"lodash.chunk": "^4.2.0",
|
|
@@ -29,9 +29,9 @@ export interface L1TxUtilsConfig {
|
|
|
29
29
|
*/
|
|
30
30
|
priorityFeeRetryBumpPercentage?: number;
|
|
31
31
|
/**
|
|
32
|
-
*
|
|
32
|
+
* Minimum priority fee per gas in Gwei. Acts as a floor for the computed priority fee.
|
|
33
33
|
*/
|
|
34
|
-
|
|
34
|
+
minimumPriorityFeePerGas?: number;
|
|
35
35
|
/**
|
|
36
36
|
* Maximum number of speed-up attempts
|
|
37
37
|
*/
|
|
@@ -90,10 +90,21 @@ export const l1TxUtilsConfigMappings: ConfigMappingsType<L1TxUtilsConfig> = {
|
|
|
90
90
|
env: 'L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE',
|
|
91
91
|
...numberConfigHelper(50),
|
|
92
92
|
},
|
|
93
|
-
|
|
94
|
-
description:
|
|
95
|
-
|
|
96
|
-
|
|
93
|
+
minimumPriorityFeePerGas: {
|
|
94
|
+
description:
|
|
95
|
+
'Minimum priority fee per gas in Gwei. Acts as a floor for the computed priority fee. If network conditions require a higher fee, the higher fee will be used.',
|
|
96
|
+
env: 'L1_MINIMUM_PRIORITY_FEE_PER_GAS_GWEI',
|
|
97
|
+
fallback: ['L1_FIXED_PRIORITY_FEE_PER_GAS', 'L1_FIXED_PRIORITY_FEE_PER_GAS_GWEI'],
|
|
98
|
+
deprecatedFallback: [
|
|
99
|
+
{
|
|
100
|
+
env: 'L1_FIXED_PRIORITY_FEE_PER_GAS',
|
|
101
|
+
message: deprecatedFixedFeeMessage('L1_FIXED_PRIORITY_FEE_PER_GAS'),
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
env: 'L1_FIXED_PRIORITY_FEE_PER_GAS_GWEI',
|
|
105
|
+
message: deprecatedFixedFeeMessage('L1_FIXED_PRIORITY_FEE_PER_GAS_GWEI'),
|
|
106
|
+
},
|
|
107
|
+
],
|
|
97
108
|
...floatConfigHelper(0),
|
|
98
109
|
},
|
|
99
110
|
maxSpeedUpAttempts: {
|
|
@@ -141,3 +152,10 @@ export const defaultL1TxUtilsConfig = getDefaultConfig<L1TxUtilsConfig>(
|
|
|
141
152
|
export function getL1TxUtilsConfigEnvVars(): L1TxUtilsConfig {
|
|
142
153
|
return getConfigFromMappings(l1TxUtilsConfigMappings);
|
|
143
154
|
}
|
|
155
|
+
|
|
156
|
+
function deprecatedFixedFeeMessage(envVar: string): string {
|
|
157
|
+
return (
|
|
158
|
+
`Environment variable ${envVar} is deprecated. It is now used as a MINIMUM priority fee rather than a fixed value. ` +
|
|
159
|
+
'Please use L1_MINIMUM_PRIORITY_FEE_PER_GAS_GWEI instead. If network conditions require a higher fee, the higher fee will be used.'
|
|
160
|
+
);
|
|
161
|
+
}
|
|
@@ -199,21 +199,18 @@ export class ReadOnlyL1TxUtils {
|
|
|
199
199
|
() => this.client.getBlock({ blockTag: 'latest' }),
|
|
200
200
|
'Getting latest block',
|
|
201
201
|
);
|
|
202
|
-
const networkEstimatePromise =
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
() => this.client.getFeeHistory({ blockCount: HISTORICAL_BLOCK_COUNT, rewardPercentiles: [75] }),
|
|
215
|
-
'Getting fee history',
|
|
216
|
-
);
|
|
202
|
+
const networkEstimatePromise = this.tryTwice(
|
|
203
|
+
() => this.client.estimateMaxPriorityFeePerGas(),
|
|
204
|
+
'Estimating max priority fee per gas',
|
|
205
|
+
);
|
|
206
|
+
const pendingBlockPromise = this.tryTwice(
|
|
207
|
+
() => this.client.getBlock({ blockTag: 'pending', includeTransactions: true }),
|
|
208
|
+
'Getting pending block',
|
|
209
|
+
);
|
|
210
|
+
const feeHistoryPromise = this.tryTwice(
|
|
211
|
+
() => this.client.getFeeHistory({ blockCount: HISTORICAL_BLOCK_COUNT, rewardPercentiles: [75] }),
|
|
212
|
+
'Getting fee history',
|
|
213
|
+
);
|
|
217
214
|
const blobBaseFeePromise = isBlobTx
|
|
218
215
|
? this.tryTwice(() => this.client.getBlobBaseFee(), 'Getting blob base fee')
|
|
219
216
|
: null;
|
|
@@ -221,9 +218,9 @@ export class ReadOnlyL1TxUtils {
|
|
|
221
218
|
const [latestBlockResult, networkEstimateResult, pendingBlockResult, feeHistoryResult, blobBaseFeeResult] =
|
|
222
219
|
await Promise.allSettled([
|
|
223
220
|
latestBlockPromise,
|
|
224
|
-
networkEstimatePromise
|
|
225
|
-
pendingBlockPromise
|
|
226
|
-
feeHistoryPromise
|
|
221
|
+
networkEstimatePromise,
|
|
222
|
+
pendingBlockPromise,
|
|
223
|
+
feeHistoryPromise,
|
|
227
224
|
blobBaseFeePromise ?? Promise.resolve(0n),
|
|
228
225
|
]);
|
|
229
226
|
|
|
@@ -243,15 +240,24 @@ export class ReadOnlyL1TxUtils {
|
|
|
243
240
|
this.logger?.warn('Failed to get L1 blob base fee', attempt);
|
|
244
241
|
}
|
|
245
242
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
243
|
+
// Get competitive priority fee
|
|
244
|
+
let priorityFee = this.getCompetitivePriorityFee(networkEstimateResult, pendingBlockResult, feeHistoryResult);
|
|
245
|
+
|
|
246
|
+
// Apply minimum priority fee as a floor if configured
|
|
247
|
+
if (gasConfig.minimumPriorityFeePerGas) {
|
|
248
|
+
const minimumFee = BigInt(Math.trunc(gasConfig.minimumPriorityFeePerGas * Number(WEI_CONST)));
|
|
249
|
+
if (minimumFee > priorityFee) {
|
|
250
|
+
this.logger?.debug('Using minimum priority fee as floor', {
|
|
251
|
+
minimumPriorityFeePerGas: formatGwei(minimumFee),
|
|
252
|
+
competitiveFee: formatGwei(priorityFee),
|
|
253
|
+
});
|
|
254
|
+
priorityFee = minimumFee;
|
|
255
|
+
} else {
|
|
256
|
+
this.logger?.debug('Competitive fee exceeds minimum, using competitive fee', {
|
|
257
|
+
minimumPriorityFeePerGas: formatGwei(minimumFee),
|
|
258
|
+
competitiveFee: formatGwei(priorityFee),
|
|
259
|
+
});
|
|
260
|
+
}
|
|
255
261
|
}
|
|
256
262
|
let maxFeePerGas = baseFee;
|
|
257
263
|
|
|
@@ -280,18 +286,15 @@ export class ReadOnlyL1TxUtils {
|
|
|
280
286
|
(previousGasPrice!.maxPriorityFeePerGas * (100_00n + BigInt(bumpPercentage * 1_00))) / 100_00n;
|
|
281
287
|
const minMaxFee = (previousGasPrice!.maxFeePerGas * (100_00n + BigInt(bumpPercentage * 1_00))) / 100_00n;
|
|
282
288
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
// Apply bump percentage to competitive fee
|
|
286
|
-
competitivePriorityFee = (priorityFee * (100_00n + BigInt(configBump * 1_00))) / 100_00n;
|
|
289
|
+
// Apply bump percentage to competitive fee
|
|
290
|
+
const competitivePriorityFee = (priorityFee * (100_00n + BigInt(configBump * 1_00))) / 100_00n;
|
|
287
291
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
}
|
|
292
|
+
this.logger?.debug(`Speed-up attempt ${attempt}: using competitive fee strategy`, {
|
|
293
|
+
networkEstimate: formatGwei(priorityFee),
|
|
294
|
+
competitiveFee: formatGwei(competitivePriorityFee),
|
|
295
|
+
minRequired: formatGwei(minPriorityFee),
|
|
296
|
+
bumpPercentage: configBump,
|
|
297
|
+
});
|
|
295
298
|
|
|
296
299
|
// Use maximum between competitive fee and minimum required bump
|
|
297
300
|
const finalPriorityFee = competitivePriorityFee > minPriorityFee ? competitivePriorityFee : minPriorityFee;
|
|
@@ -302,20 +305,16 @@ export class ReadOnlyL1TxUtils {
|
|
|
302
305
|
maxFeePerGas += finalPriorityFee;
|
|
303
306
|
maxFeePerGas = maxFeePerGas > minMaxFee ? maxFeePerGas : minMaxFee;
|
|
304
307
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
});
|
|
309
|
-
}
|
|
308
|
+
this.logger?.debug(`Speed-up fee decision: using ${feeSource} fee`, {
|
|
309
|
+
finalPriorityFee: formatGwei(finalPriorityFee),
|
|
310
|
+
});
|
|
310
311
|
} else {
|
|
311
312
|
// First attempt: apply configured bump percentage to competitive fee
|
|
312
313
|
// multiply by 100 & divide by 100 to maintain some precision
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
});
|
|
318
|
-
}
|
|
314
|
+
priorityFee = (priorityFee * (100_00n + BigInt((gasConfig.priorityFeeBumpPercentage || 0) * 1_00))) / 100_00n;
|
|
315
|
+
this.logger?.debug('Initial transaction: using competitive fee from market analysis', {
|
|
316
|
+
networkEstimate: formatGwei(priorityFee),
|
|
317
|
+
});
|
|
319
318
|
maxFeePerGas += priorityFee;
|
|
320
319
|
}
|
|
321
320
|
|