@aztec/ethereum 0.0.1-commit.fcb71a6 → 0.0.1-commit.ff7989d6c
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/config.d.ts +15 -28
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +50 -57
- package/dest/contracts/empire_base.d.ts +3 -1
- package/dest/contracts/empire_base.d.ts.map +1 -1
- package/dest/contracts/empire_slashing_proposer.d.ts +3 -1
- package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
- package/dest/contracts/empire_slashing_proposer.js +22 -15
- package/dest/contracts/fee_asset_handler.d.ts +6 -5
- package/dest/contracts/fee_asset_handler.d.ts.map +1 -1
- package/dest/contracts/fee_asset_handler.js +11 -9
- package/dest/contracts/fee_asset_price_oracle.d.ts +101 -0
- package/dest/contracts/fee_asset_price_oracle.d.ts.map +1 -0
- package/dest/contracts/fee_asset_price_oracle.js +651 -0
- package/dest/contracts/governance.d.ts +3 -1
- package/dest/contracts/governance.d.ts.map +1 -1
- package/dest/contracts/governance.js +14 -4
- package/dest/contracts/governance_proposer.d.ts +3 -1
- package/dest/contracts/governance_proposer.d.ts.map +1 -1
- package/dest/contracts/governance_proposer.js +395 -9
- package/dest/contracts/inbox.d.ts +18 -1
- package/dest/contracts/inbox.d.ts.map +1 -1
- package/dest/contracts/inbox.js +32 -1
- package/dest/contracts/index.d.ts +4 -1
- package/dest/contracts/index.d.ts.map +1 -1
- package/dest/contracts/index.js +3 -0
- package/dest/contracts/log.d.ts +13 -0
- package/dest/contracts/log.d.ts.map +1 -0
- package/dest/contracts/log.js +1 -0
- package/dest/contracts/multicall.d.ts +1 -1
- package/dest/contracts/multicall.d.ts.map +1 -1
- package/dest/contracts/multicall.js +2 -1
- package/dest/contracts/outbox.d.ts +41 -0
- package/dest/contracts/outbox.d.ts.map +1 -0
- package/dest/contracts/outbox.js +86 -0
- package/dest/contracts/rollup.d.ts +161 -96
- package/dest/contracts/rollup.d.ts.map +1 -1
- package/dest/contracts/rollup.js +677 -132
- package/dest/contracts/tally_slashing_proposer.d.ts +1 -1
- package/dest/contracts/tally_slashing_proposer.d.ts.map +1 -1
- package/dest/contracts/tally_slashing_proposer.js +8 -1
- package/dest/deploy_aztec_l1_contracts.d.ts +16 -4
- package/dest/deploy_aztec_l1_contracts.d.ts.map +1 -1
- package/dest/deploy_aztec_l1_contracts.js +110 -33
- package/dest/deploy_l1_contract.js +3 -3
- package/dest/generated/l1-contracts-defaults.d.ts +30 -0
- package/dest/generated/l1-contracts-defaults.d.ts.map +1 -0
- package/dest/generated/l1-contracts-defaults.js +30 -0
- package/dest/l1_artifacts.d.ts +5877 -1515
- package/dest/l1_artifacts.d.ts.map +1 -1
- package/dest/l1_tx_utils/config.d.ts +7 -1
- package/dest/l1_tx_utils/config.d.ts.map +1 -1
- package/dest/l1_tx_utils/config.js +14 -1
- package/dest/l1_tx_utils/constants.d.ts +1 -1
- package/dest/l1_tx_utils/constants.js +2 -2
- package/dest/l1_tx_utils/factory.d.ts +18 -10
- package/dest/l1_tx_utils/factory.d.ts.map +1 -1
- package/dest/l1_tx_utils/factory.js +17 -7
- package/dest/l1_tx_utils/fee-strategies/index.d.ts +3 -2
- package/dest/l1_tx_utils/fee-strategies/index.d.ts.map +1 -1
- package/dest/l1_tx_utils/fee-strategies/index.js +2 -1
- package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts +2 -12
- package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts.map +1 -1
- package/dest/l1_tx_utils/fee-strategies/p75_competitive.js +36 -18
- package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts +2 -11
- package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts.map +1 -1
- package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.js +37 -19
- package/dest/l1_tx_utils/fee-strategies/types.d.ts +14 -27
- package/dest/l1_tx_utils/fee-strategies/types.d.ts.map +1 -1
- package/dest/l1_tx_utils/fee-strategies/types.js +0 -21
- package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts +15 -15
- package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts.map +1 -1
- package/dest/l1_tx_utils/forwarder_l1_tx_utils.js +9 -15
- package/dest/l1_tx_utils/index-blobs.d.ts +3 -3
- package/dest/l1_tx_utils/index-blobs.d.ts.map +1 -1
- package/dest/l1_tx_utils/index-blobs.js +2 -2
- package/dest/l1_tx_utils/index.d.ts +2 -1
- package/dest/l1_tx_utils/index.d.ts.map +1 -1
- package/dest/l1_tx_utils/index.js +1 -0
- package/dest/l1_tx_utils/l1_fee_analyzer.d.ts +2 -2
- package/dest/l1_tx_utils/l1_fee_analyzer.d.ts.map +1 -1
- package/dest/l1_tx_utils/l1_fee_analyzer.js +3 -3
- package/dest/l1_tx_utils/l1_tx_utils.d.ts +15 -5
- package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -1
- package/dest/l1_tx_utils/l1_tx_utils.js +47 -13
- package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts +1 -5
- package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -1
- package/dest/l1_tx_utils/readonly_l1_tx_utils.js +17 -54
- package/dest/l1_tx_utils/tx_delayer.d.ts +56 -0
- package/dest/l1_tx_utils/tx_delayer.d.ts.map +1 -0
- package/dest/{test → l1_tx_utils}/tx_delayer.js +62 -34
- package/dest/publisher_manager.d.ts +3 -2
- package/dest/publisher_manager.d.ts.map +1 -1
- package/dest/publisher_manager.js +2 -2
- package/dest/queries.d.ts +2 -2
- package/dest/queries.d.ts.map +1 -1
- package/dest/queries.js +6 -3
- package/dest/test/chain_monitor.js +1 -2
- package/dest/test/eth_cheat_codes.d.ts +13 -1
- package/dest/test/eth_cheat_codes.d.ts.map +1 -1
- package/dest/test/index.d.ts +1 -3
- package/dest/test/index.d.ts.map +1 -1
- package/dest/test/index.js +0 -2
- package/dest/test/rollup_cheat_codes.d.ts +5 -2
- package/dest/test/rollup_cheat_codes.d.ts.map +1 -1
- package/dest/test/rollup_cheat_codes.js +19 -2
- package/dest/test/start_anvil.js +1 -1
- package/dest/test/upgrade_utils.js +2 -2
- package/dest/utils.d.ts +2 -1
- package/dest/utils.d.ts.map +1 -1
- package/dest/utils.js +46 -0
- package/package.json +8 -7
- package/src/config.ts +58 -56
- package/src/contracts/README.md +157 -0
- package/src/contracts/empire_base.ts +2 -0
- package/src/contracts/empire_slashing_proposer.ts +22 -27
- package/src/contracts/fee_asset_handler.ts +10 -7
- package/src/contracts/fee_asset_price_oracle.ts +280 -0
- package/src/contracts/governance.ts +13 -4
- package/src/contracts/governance_proposer.ts +10 -1
- package/src/contracts/inbox.ts +48 -1
- package/src/contracts/index.ts +3 -0
- package/src/contracts/log.ts +13 -0
- package/src/contracts/multicall.ts +5 -2
- package/src/contracts/outbox.ts +98 -0
- package/src/contracts/rollup.ts +348 -100
- package/src/contracts/tally_slashing_proposer.ts +5 -1
- package/src/deploy_aztec_l1_contracts.ts +135 -42
- package/src/deploy_l1_contract.ts +3 -3
- package/src/generated/l1-contracts-defaults.ts +32 -0
- package/src/l1_tx_utils/config.ts +20 -0
- package/src/l1_tx_utils/constants.ts +2 -2
- package/src/l1_tx_utils/factory.ts +31 -31
- package/src/l1_tx_utils/fee-strategies/index.ts +1 -1
- package/src/l1_tx_utils/fee-strategies/p75_competitive.ts +46 -42
- package/src/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.ts +49 -45
- package/src/l1_tx_utils/fee-strategies/types.ts +14 -46
- package/src/l1_tx_utils/forwarder_l1_tx_utils.ts +43 -54
- package/src/l1_tx_utils/index-blobs.ts +2 -2
- package/src/l1_tx_utils/index.ts +1 -0
- package/src/l1_tx_utils/l1_fee_analyzer.ts +2 -3
- package/src/l1_tx_utils/l1_tx_utils.ts +52 -17
- package/src/l1_tx_utils/readonly_l1_tx_utils.ts +23 -62
- package/src/{test → l1_tx_utils}/tx_delayer.ts +78 -50
- package/src/publisher_manager.ts +4 -2
- package/src/queries.ts +5 -3
- package/src/test/chain_monitor.ts +1 -1
- package/src/test/index.ts +0 -2
- package/src/test/rollup_cheat_codes.ts +21 -3
- package/src/test/start_anvil.ts +1 -1
- package/src/test/upgrade_utils.ts +2 -2
- package/src/utils.ts +53 -0
- package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts +0 -26
- package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts.map +0 -1
- package/dest/l1_tx_utils/l1_tx_utils_with_blobs.js +0 -26
- package/dest/test/delayed_tx_utils.d.ts +0 -13
- package/dest/test/delayed_tx_utils.d.ts.map +0 -1
- package/dest/test/delayed_tx_utils.js +0 -28
- package/dest/test/tx_delayer.d.ts +0 -36
- package/dest/test/tx_delayer.d.ts.map +0 -1
- package/src/l1_tx_utils/l1_tx_utils_with_blobs.ts +0 -77
- package/src/test/delayed_tx_utils.ts +0 -52
|
@@ -12,50 +12,54 @@ import {
|
|
|
12
12
|
type PriorityFeeStrategyResult,
|
|
13
13
|
} from './types.js';
|
|
14
14
|
|
|
15
|
-
/**
|
|
16
|
-
* Type for the promises required by the competitive strategy
|
|
17
|
-
*/
|
|
18
|
-
type P75AllTxsStrategyPromises = {
|
|
19
|
-
networkEstimate: Promise<bigint>;
|
|
20
|
-
pendingBlock: Promise<Awaited<ReturnType<ViemClient['getBlock']>> | null>;
|
|
21
|
-
feeHistory: Promise<Awaited<ReturnType<ViemClient['getFeeHistory']>> | null>;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
15
|
/**
|
|
25
16
|
* Our current competitive priority fee strategy.
|
|
26
17
|
* Analyzes p75 of pending transactions and 5-block fee history to determine a competitive priority fee.
|
|
27
18
|
* Falls back to network estimate if data is unavailable.
|
|
28
19
|
*/
|
|
29
|
-
export const P75AllTxsPriorityFeeStrategy: PriorityFeeStrategy
|
|
20
|
+
export const P75AllTxsPriorityFeeStrategy: PriorityFeeStrategy = {
|
|
30
21
|
name: 'Competitive (P75 + History) - CURRENT',
|
|
31
22
|
id: 'p75_pending_txs_and_history_all_txs',
|
|
32
23
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
24
|
+
async execute(client: ViemClient, context: PriorityFeeStrategyContext): Promise<PriorityFeeStrategyResult> {
|
|
25
|
+
const { isBlobTx, logger } = context;
|
|
26
|
+
|
|
27
|
+
// Fire all RPC calls in parallel
|
|
28
|
+
const [latestBlockResult, blobBaseFeeResult, networkEstimateResult, pendingBlockResult, feeHistoryResult] =
|
|
29
|
+
await Promise.allSettled([
|
|
30
|
+
client.getBlock({ blockTag: 'latest' }),
|
|
31
|
+
isBlobTx ? client.getBlobBaseFee() : Promise.resolve(undefined),
|
|
32
|
+
client.estimateMaxPriorityFeePerGas().catch(() => 0n),
|
|
33
|
+
client.getBlock({ blockTag: 'pending', includeTransactions: true }).catch(() => null),
|
|
34
|
+
client
|
|
35
|
+
.getFeeHistory({
|
|
36
|
+
blockCount: HISTORICAL_BLOCK_COUNT,
|
|
37
|
+
rewardPercentiles: [75],
|
|
38
|
+
blockTag: 'latest',
|
|
39
|
+
})
|
|
40
|
+
.catch(() => null),
|
|
41
|
+
]);
|
|
42
|
+
|
|
43
|
+
// Extract latest block
|
|
44
|
+
if (latestBlockResult.status === 'rejected') {
|
|
45
|
+
throw new Error(`Failed to get latest block: ${latestBlockResult.reason}`);
|
|
46
|
+
}
|
|
47
|
+
const latestBlock = latestBlockResult.value;
|
|
48
|
+
|
|
49
|
+
// Extract blob base fee (only for blob txs)
|
|
50
|
+
let blobBaseFee: bigint | undefined;
|
|
51
|
+
if (isBlobTx) {
|
|
52
|
+
if (blobBaseFeeResult.status === 'fulfilled' && typeof blobBaseFeeResult.value === 'bigint') {
|
|
53
|
+
blobBaseFee = blobBaseFeeResult.value;
|
|
54
|
+
} else {
|
|
55
|
+
logger?.warn('Failed to get L1 blob base fee');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
54
58
|
|
|
55
|
-
// Extract network estimate
|
|
59
|
+
// Extract network estimate
|
|
56
60
|
const networkEstimate =
|
|
57
|
-
|
|
58
|
-
?
|
|
61
|
+
networkEstimateResult.status === 'fulfilled' && typeof networkEstimateResult.value === 'bigint'
|
|
62
|
+
? networkEstimateResult.value
|
|
59
63
|
: 0n;
|
|
60
64
|
|
|
61
65
|
let competitiveFee = networkEstimate;
|
|
@@ -63,8 +67,8 @@ export const P75AllTxsPriorityFeeStrategy: PriorityFeeStrategy<P75AllTxsStrategy
|
|
|
63
67
|
networkEstimateGwei: formatGwei(networkEstimate),
|
|
64
68
|
};
|
|
65
69
|
|
|
66
|
-
// Extract pending block
|
|
67
|
-
const pendingBlock =
|
|
70
|
+
// Extract pending block
|
|
71
|
+
const pendingBlock = pendingBlockResult.status === 'fulfilled' ? pendingBlockResult.value : null;
|
|
68
72
|
|
|
69
73
|
// Analyze pending block transactions
|
|
70
74
|
if (pendingBlock?.transactions && pendingBlock.transactions.length > 0) {
|
|
@@ -73,9 +77,7 @@ export const P75AllTxsPriorityFeeStrategy: PriorityFeeStrategy<P75AllTxsStrategy
|
|
|
73
77
|
if (typeof tx === 'string') {
|
|
74
78
|
return 0n;
|
|
75
79
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return fee;
|
|
80
|
+
return tx.maxPriorityFeePerGas || 0n;
|
|
79
81
|
})
|
|
80
82
|
.filter((fee: bigint) => fee > 0n);
|
|
81
83
|
|
|
@@ -97,8 +99,8 @@ export const P75AllTxsPriorityFeeStrategy: PriorityFeeStrategy<P75AllTxsStrategy
|
|
|
97
99
|
}
|
|
98
100
|
}
|
|
99
101
|
|
|
100
|
-
// Extract fee history
|
|
101
|
-
const feeHistory =
|
|
102
|
+
// Extract fee history
|
|
103
|
+
const feeHistory = feeHistoryResult.status === 'fulfilled' ? feeHistoryResult.value : null;
|
|
102
104
|
|
|
103
105
|
// Analyze fee history
|
|
104
106
|
if (feeHistory?.reward && feeHistory.reward.length > 0) {
|
|
@@ -132,7 +134,7 @@ export const P75AllTxsPriorityFeeStrategy: PriorityFeeStrategy<P75AllTxsStrategy
|
|
|
132
134
|
// Sanity check: cap competitive fee at 100x network estimate to avoid using unrealistic fees
|
|
133
135
|
const maxReasonableFee = networkEstimate * 100n;
|
|
134
136
|
if (competitiveFee > maxReasonableFee && networkEstimate > 0n) {
|
|
135
|
-
logger?.
|
|
137
|
+
logger?.debug('Competitive fee exceeds sanity cap, using capped value', {
|
|
136
138
|
competitiveFee: formatGwei(competitiveFee),
|
|
137
139
|
networkEstimate: formatGwei(networkEstimate),
|
|
138
140
|
cappedTo: formatGwei(maxReasonableFee),
|
|
@@ -153,6 +155,8 @@ export const P75AllTxsPriorityFeeStrategy: PriorityFeeStrategy<P75AllTxsStrategy
|
|
|
153
155
|
|
|
154
156
|
return {
|
|
155
157
|
priorityFee: competitiveFee,
|
|
158
|
+
latestBlock,
|
|
159
|
+
blobBaseFee,
|
|
156
160
|
debugInfo,
|
|
157
161
|
};
|
|
158
162
|
},
|
|
@@ -12,15 +12,6 @@ import {
|
|
|
12
12
|
type PriorityFeeStrategyResult,
|
|
13
13
|
} from './types.js';
|
|
14
14
|
|
|
15
|
-
/**
|
|
16
|
-
* Type for the promises required by the competitive strategy
|
|
17
|
-
*/
|
|
18
|
-
type P75AllTxsStrategyPromises = {
|
|
19
|
-
networkEstimate: Promise<bigint>;
|
|
20
|
-
pendingBlock: Promise<Awaited<ReturnType<ViemClient['getBlock']>> | null>;
|
|
21
|
-
feeHistory: Promise<Awaited<ReturnType<ViemClient['getFeeHistory']>> | null>;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
15
|
/**
|
|
25
16
|
* Fetches historical blocks and calculates reward percentiles for blob transactions only.
|
|
26
17
|
* Returns data in the same format as getFeeHistory for easy drop-in replacement.
|
|
@@ -114,38 +105,51 @@ export async function getBlobPriorityFeeHistory(
|
|
|
114
105
|
* Analyzes p75 of pending transactions and 5-block fee history to determine a competitive priority fee.
|
|
115
106
|
* Falls back to network estimate if data is unavailable.
|
|
116
107
|
*/
|
|
117
|
-
export const P75BlobTxsOnlyPriorityFeeStrategy: PriorityFeeStrategy
|
|
108
|
+
export const P75BlobTxsOnlyPriorityFeeStrategy: PriorityFeeStrategy = {
|
|
118
109
|
name: 'Competitive (P75 + History) - Blob Txs Only',
|
|
119
110
|
id: 'p75_pending_txs_and_history_blob_txs_only',
|
|
120
111
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
:
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
112
|
+
async execute(client: ViemClient, context: PriorityFeeStrategyContext): Promise<PriorityFeeStrategyResult> {
|
|
113
|
+
const { isBlobTx, logger } = context;
|
|
114
|
+
|
|
115
|
+
// Fire all RPC calls in parallel
|
|
116
|
+
const [latestBlockResult, blobBaseFeeResult, networkEstimateResult, pendingBlockResult, feeHistoryResult] =
|
|
117
|
+
await Promise.allSettled([
|
|
118
|
+
client.getBlock({ blockTag: 'latest' }),
|
|
119
|
+
isBlobTx ? client.getBlobBaseFee() : Promise.resolve(undefined),
|
|
120
|
+
client.estimateMaxPriorityFeePerGas().catch(() => 0n),
|
|
121
|
+
client.getBlock({ blockTag: 'pending', includeTransactions: true }).catch(() => null),
|
|
122
|
+
isBlobTx
|
|
123
|
+
? getBlobPriorityFeeHistory(client, HISTORICAL_BLOCK_COUNT, [75])
|
|
124
|
+
: client
|
|
125
|
+
.getFeeHistory({
|
|
126
|
+
blockCount: HISTORICAL_BLOCK_COUNT,
|
|
127
|
+
rewardPercentiles: [75],
|
|
128
|
+
blockTag: 'latest',
|
|
129
|
+
})
|
|
130
|
+
.catch(() => null),
|
|
131
|
+
]);
|
|
132
|
+
|
|
133
|
+
// Extract latest block (required)
|
|
134
|
+
if (latestBlockResult.status === 'rejected') {
|
|
135
|
+
throw new Error(`Failed to get latest block: ${latestBlockResult.reason}`);
|
|
136
|
+
}
|
|
137
|
+
const latestBlock = latestBlockResult.value;
|
|
138
|
+
|
|
139
|
+
// Extract blob base fee (only for blob txs)
|
|
140
|
+
let blobBaseFee: bigint | undefined;
|
|
141
|
+
if (isBlobTx) {
|
|
142
|
+
if (blobBaseFeeResult.status === 'fulfilled' && typeof blobBaseFeeResult.value === 'bigint') {
|
|
143
|
+
blobBaseFee = blobBaseFeeResult.value;
|
|
144
|
+
} else {
|
|
145
|
+
logger?.warn('Failed to get L1 blob base fee');
|
|
146
|
+
}
|
|
147
|
+
}
|
|
144
148
|
|
|
145
|
-
// Extract network estimate
|
|
149
|
+
// Extract network estimate
|
|
146
150
|
const networkEstimate =
|
|
147
|
-
|
|
148
|
-
?
|
|
151
|
+
networkEstimateResult.status === 'fulfilled' && typeof networkEstimateResult.value === 'bigint'
|
|
152
|
+
? networkEstimateResult.value
|
|
149
153
|
: 0n;
|
|
150
154
|
|
|
151
155
|
let competitiveFee = networkEstimate;
|
|
@@ -153,8 +157,8 @@ export const P75BlobTxsOnlyPriorityFeeStrategy: PriorityFeeStrategy<P75AllTxsStr
|
|
|
153
157
|
networkEstimateGwei: formatGwei(networkEstimate),
|
|
154
158
|
};
|
|
155
159
|
|
|
156
|
-
// Extract pending block
|
|
157
|
-
const pendingBlock =
|
|
160
|
+
// Extract pending block
|
|
161
|
+
const pendingBlock = pendingBlockResult.status === 'fulfilled' ? pendingBlockResult.value : null;
|
|
158
162
|
|
|
159
163
|
// Analyze pending block transactions
|
|
160
164
|
if (pendingBlock?.transactions && pendingBlock.transactions.length > 0) {
|
|
@@ -163,14 +167,12 @@ export const P75BlobTxsOnlyPriorityFeeStrategy: PriorityFeeStrategy<P75AllTxsStr
|
|
|
163
167
|
if (typeof tx === 'string') {
|
|
164
168
|
return 0n;
|
|
165
169
|
}
|
|
166
|
-
if (
|
|
170
|
+
if (isBlobTx) {
|
|
167
171
|
if (!isBlobTransaction(tx)) {
|
|
168
172
|
return 0n;
|
|
169
173
|
}
|
|
170
174
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
return fee;
|
|
175
|
+
return tx.maxPriorityFeePerGas || 0n;
|
|
174
176
|
})
|
|
175
177
|
.filter((fee: bigint) => fee > 0n);
|
|
176
178
|
|
|
@@ -191,8 +193,8 @@ export const P75BlobTxsOnlyPriorityFeeStrategy: PriorityFeeStrategy<P75AllTxsStr
|
|
|
191
193
|
}
|
|
192
194
|
}
|
|
193
195
|
|
|
194
|
-
// Extract fee history
|
|
195
|
-
const feeHistory =
|
|
196
|
+
// Extract fee history
|
|
197
|
+
const feeHistory = feeHistoryResult.status === 'fulfilled' ? feeHistoryResult.value : null;
|
|
196
198
|
|
|
197
199
|
// Analyze fee history
|
|
198
200
|
if (feeHistory?.reward && feeHistory.reward.length > 0) {
|
|
@@ -205,7 +207,7 @@ export const P75BlobTxsOnlyPriorityFeeStrategy: PriorityFeeStrategy<P75AllTxsStr
|
|
|
205
207
|
|
|
206
208
|
// Debug: Log suspicious fees from history
|
|
207
209
|
if (medianHistoricalFee > 100n * WEI_CONST) {
|
|
208
|
-
logger?.
|
|
210
|
+
logger?.debug('Suspicious high fee in history', {
|
|
209
211
|
historicalMedian: formatGwei(medianHistoricalFee),
|
|
210
212
|
allP75Fees: percentile75Fees.map(f => formatGwei(f)),
|
|
211
213
|
});
|
|
@@ -235,6 +237,8 @@ export const P75BlobTxsOnlyPriorityFeeStrategy: PriorityFeeStrategy<P75AllTxsStr
|
|
|
235
237
|
|
|
236
238
|
return {
|
|
237
239
|
priorityFee: competitiveFee,
|
|
240
|
+
latestBlock,
|
|
241
|
+
blobBaseFee,
|
|
238
242
|
debugInfo,
|
|
239
243
|
};
|
|
240
244
|
},
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { Logger } from '@aztec/foundation/log';
|
|
2
2
|
|
|
3
|
+
import type { Block } from 'viem';
|
|
4
|
+
|
|
3
5
|
import type { ViemClient } from '../../types.js';
|
|
4
6
|
import type { L1TxUtilsConfig } from '../config.js';
|
|
5
7
|
|
|
@@ -14,12 +16,16 @@ export const HISTORICAL_BLOCK_COUNT = 5;
|
|
|
14
16
|
export interface PriorityFeeStrategyResult {
|
|
15
17
|
/** The calculated priority fee in wei */
|
|
16
18
|
priorityFee: bigint;
|
|
19
|
+
/** The latest block (fetched as part of the strategy) */
|
|
20
|
+
latestBlock: Block;
|
|
21
|
+
/** The blob base fee (only present for blob transactions) */
|
|
22
|
+
blobBaseFee?: bigint;
|
|
17
23
|
/** Optional debug info about how the fee was calculated */
|
|
18
24
|
debugInfo?: Record<string, string | number>;
|
|
19
25
|
}
|
|
20
26
|
|
|
21
27
|
/**
|
|
22
|
-
* Context passed to the strategy
|
|
28
|
+
* Context passed to the strategy function
|
|
23
29
|
*/
|
|
24
30
|
export interface PriorityFeeStrategyContext {
|
|
25
31
|
/** Gas configuration */
|
|
@@ -32,57 +38,19 @@ export interface PriorityFeeStrategyContext {
|
|
|
32
38
|
|
|
33
39
|
/**
|
|
34
40
|
* A strategy for calculating the priority fee for L1 transactions.
|
|
35
|
-
*
|
|
36
|
-
*
|
|
41
|
+
* The function handles all RPC calls and returns
|
|
42
|
+
* the priority fee, along with any block data needed by the caller.
|
|
37
43
|
*/
|
|
38
|
-
export
|
|
44
|
+
export type PriorityFeeStrategy = {
|
|
39
45
|
/** Human-readable name for logging */
|
|
40
46
|
name: string;
|
|
41
47
|
/** Unique identifier for metrics */
|
|
42
48
|
id: string;
|
|
43
49
|
/**
|
|
44
|
-
*
|
|
45
|
-
* These will be run in parallel with Promise.allSettled.
|
|
50
|
+
* Calculate the priority fee.
|
|
46
51
|
* @param client - The viem client to use for RPC calls
|
|
47
|
-
* @returns An object of promises keyed by name
|
|
48
|
-
*/
|
|
49
|
-
getRequiredPromises(client: ViemClient, opts: Partial<PriorityFeeStrategyContext>): TPromises;
|
|
50
|
-
/**
|
|
51
|
-
* Calculate the priority fee based on the settled promise results.
|
|
52
|
-
* @param results - The settled results of the promises from getRequiredPromises
|
|
53
52
|
* @param context - Contains gas config, whether it's a blob tx, and logger
|
|
54
|
-
* @returns The calculated priority fee result
|
|
53
|
+
* @returns The calculated priority fee result including block data
|
|
55
54
|
*/
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
context: PriorityFeeStrategyContext,
|
|
59
|
-
): PriorityFeeStrategyResult;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Helper function to execute a strategy's promises and calculate the result.
|
|
64
|
-
* This can be used by both L1FeeAnalyzer and ReadOnlyL1TxUtils.
|
|
65
|
-
* @param strategy - The strategy to execute
|
|
66
|
-
* @param client - The viem client to use for RPC calls
|
|
67
|
-
* @param context - The context for calculation
|
|
68
|
-
* @returns The strategy result
|
|
69
|
-
*/
|
|
70
|
-
export async function executeStrategy<TPromises extends Record<string, Promise<any>>>(
|
|
71
|
-
strategy: PriorityFeeStrategy<TPromises>,
|
|
72
|
-
client: ViemClient,
|
|
73
|
-
context: PriorityFeeStrategyContext,
|
|
74
|
-
): Promise<PriorityFeeStrategyResult> {
|
|
75
|
-
const promises = strategy.getRequiredPromises(client, { isBlobTx: context.isBlobTx });
|
|
76
|
-
const keys = Object.keys(promises) as Array<keyof TPromises>;
|
|
77
|
-
const promiseArray = keys.map(k => promises[k]);
|
|
78
|
-
|
|
79
|
-
const settledResults = await Promise.allSettled(promiseArray);
|
|
80
|
-
|
|
81
|
-
// Reconstruct the results object with the same keys, preserving the type mapping
|
|
82
|
-
const results = {} as { [K in keyof TPromises]: PromiseSettledResult<Awaited<TPromises[K]>> };
|
|
83
|
-
keys.forEach((key, index) => {
|
|
84
|
-
results[key] = settledResults[index] as PromiseSettledResult<Awaited<TPromises[typeof key]>>;
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
return strategy.calculate(results, context);
|
|
88
|
-
}
|
|
55
|
+
execute: (client: ViemClient, context: PriorityFeeStrategyContext) => Promise<PriorityFeeStrategyResult>;
|
|
56
|
+
};
|
|
@@ -1,25 +1,27 @@
|
|
|
1
|
+
import type { BlobKzgInstance } from '@aztec/blob-lib/types';
|
|
1
2
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
3
|
import type { Logger } from '@aztec/foundation/log';
|
|
3
4
|
import type { DateProvider } from '@aztec/foundation/timer';
|
|
4
5
|
|
|
5
6
|
import { type Hex, encodeFunctionData } from 'viem';
|
|
6
7
|
|
|
7
|
-
import type { EthSigner } from '../eth-signer/eth-signer.js';
|
|
8
8
|
import { FORWARDER_ABI } from '../forwarder_proxy.js';
|
|
9
|
-
import type {
|
|
9
|
+
import type { ViemClient } from '../types.js';
|
|
10
10
|
import type { L1TxUtilsConfig } from './config.js';
|
|
11
|
+
import type { L1SignerSource } from './factory.js';
|
|
12
|
+
import { resolveSignerSource } from './factory.js';
|
|
11
13
|
import type { IL1TxMetrics, IL1TxStore } from './interfaces.js';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
+
import { L1TxUtils } from './l1_tx_utils.js';
|
|
15
|
+
import { Delayer } from './tx_delayer.js';
|
|
14
16
|
import type { L1BlobInputs, L1TxConfig, L1TxRequest, SigningCallback } from './types.js';
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
|
-
* Extends
|
|
19
|
+
* Extends L1TxUtils to wrap all transactions through a forwarder contract.
|
|
18
20
|
* This is mainly used for testing the archiver's ability to decode transactions that go through proxies.
|
|
19
21
|
*/
|
|
20
|
-
export class ForwarderL1TxUtils extends
|
|
22
|
+
export class ForwarderL1TxUtils extends L1TxUtils {
|
|
21
23
|
constructor(
|
|
22
|
-
client: ViemClient
|
|
24
|
+
client: ViemClient,
|
|
23
25
|
senderAddress: EthAddress,
|
|
24
26
|
signingCallback: SigningCallback,
|
|
25
27
|
logger: Logger | undefined,
|
|
@@ -28,9 +30,23 @@ export class ForwarderL1TxUtils extends L1TxUtilsWithBlobs {
|
|
|
28
30
|
debugMaxGasLimit: boolean,
|
|
29
31
|
store: IL1TxStore | undefined,
|
|
30
32
|
metrics: IL1TxMetrics | undefined,
|
|
33
|
+
kzg: BlobKzgInstance | undefined,
|
|
34
|
+
delayer: Delayer | undefined,
|
|
31
35
|
private readonly forwarderAddress: EthAddress,
|
|
32
36
|
) {
|
|
33
|
-
super(
|
|
37
|
+
super(
|
|
38
|
+
client,
|
|
39
|
+
senderAddress,
|
|
40
|
+
signingCallback,
|
|
41
|
+
logger,
|
|
42
|
+
dateProvider,
|
|
43
|
+
config,
|
|
44
|
+
debugMaxGasLimit,
|
|
45
|
+
store,
|
|
46
|
+
metrics,
|
|
47
|
+
kzg,
|
|
48
|
+
delayer,
|
|
49
|
+
);
|
|
34
50
|
}
|
|
35
51
|
|
|
36
52
|
/**
|
|
@@ -61,59 +77,32 @@ export class ForwarderL1TxUtils extends L1TxUtilsWithBlobs {
|
|
|
61
77
|
}
|
|
62
78
|
}
|
|
63
79
|
|
|
64
|
-
export function
|
|
65
|
-
|
|
80
|
+
export function createForwarderL1TxUtils(
|
|
81
|
+
source: L1SignerSource,
|
|
66
82
|
forwarderAddress: EthAddress,
|
|
67
|
-
deps
|
|
83
|
+
deps?: {
|
|
68
84
|
logger?: Logger;
|
|
69
85
|
dateProvider?: DateProvider;
|
|
70
86
|
store?: IL1TxStore;
|
|
71
87
|
metrics?: IL1TxMetrics;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
88
|
+
kzg?: BlobKzgInstance;
|
|
89
|
+
delayer?: Delayer;
|
|
90
|
+
},
|
|
91
|
+
config?: Partial<L1TxUtilsConfig> & { debugMaxGasLimit?: boolean },
|
|
92
|
+
): ForwarderL1TxUtils {
|
|
93
|
+
const { client, address, signingCallback } = resolveSignerSource(source);
|
|
76
94
|
return new ForwarderL1TxUtils(
|
|
77
95
|
client,
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
deps
|
|
81
|
-
deps
|
|
82
|
-
config,
|
|
83
|
-
debugMaxGasLimit,
|
|
84
|
-
deps
|
|
85
|
-
deps
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export function createForwarderL1TxUtilsFromEthSigner(
|
|
91
|
-
client: ViemClient,
|
|
92
|
-
signer: EthSigner,
|
|
93
|
-
forwarderAddress: EthAddress,
|
|
94
|
-
deps: {
|
|
95
|
-
logger?: Logger;
|
|
96
|
-
dateProvider?: DateProvider;
|
|
97
|
-
store?: IL1TxStore;
|
|
98
|
-
metrics?: IL1TxMetrics;
|
|
99
|
-
} = {},
|
|
100
|
-
config: Partial<L1TxUtilsConfig> = {},
|
|
101
|
-
debugMaxGasLimit: boolean = false,
|
|
102
|
-
) {
|
|
103
|
-
const callback: SigningCallback = async (transaction, _signingAddress) => {
|
|
104
|
-
return (await signer.signTransaction(transaction)).toViemTransactionSignature();
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
return new ForwarderL1TxUtils(
|
|
108
|
-
client,
|
|
109
|
-
signer.address,
|
|
110
|
-
callback,
|
|
111
|
-
deps.logger,
|
|
112
|
-
deps.dateProvider,
|
|
113
|
-
config,
|
|
114
|
-
debugMaxGasLimit,
|
|
115
|
-
deps.store,
|
|
116
|
-
deps.metrics,
|
|
96
|
+
address,
|
|
97
|
+
signingCallback,
|
|
98
|
+
deps?.logger,
|
|
99
|
+
deps?.dateProvider,
|
|
100
|
+
config ?? {},
|
|
101
|
+
config?.debugMaxGasLimit ?? false,
|
|
102
|
+
deps?.store,
|
|
103
|
+
deps?.metrics,
|
|
104
|
+
deps?.kzg,
|
|
105
|
+
deps?.delayer,
|
|
117
106
|
forwarderAddress,
|
|
118
107
|
);
|
|
119
108
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
1
|
+
export { createForwarderL1TxUtils, ForwarderL1TxUtils } from './forwarder_l1_tx_utils.js';
|
|
2
|
+
export { createL1TxUtils, type L1SignerSource, resolveSignerSource } from './factory.js';
|
package/src/l1_tx_utils/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ export * from './l1_tx_utils.js';
|
|
|
8
8
|
export * from './readonly_l1_tx_utils.js';
|
|
9
9
|
export * from './signer.js';
|
|
10
10
|
export * from './types.js';
|
|
11
|
+
export * from './tx_delayer.js';
|
|
11
12
|
export * from './utils.js';
|
|
12
13
|
|
|
13
14
|
// Note: We intentionally do not export l1_tx_utils_with_blobs.js
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
DEFAULT_PRIORITY_FEE_STRATEGIES,
|
|
14
14
|
type PriorityFeeStrategy,
|
|
15
15
|
type PriorityFeeStrategyContext,
|
|
16
|
-
executeStrategy,
|
|
17
16
|
} from './fee-strategies/index.js';
|
|
18
17
|
import type { L1BlobInputs, L1TxRequest } from './types.js';
|
|
19
18
|
|
|
@@ -262,7 +261,7 @@ export class L1FeeAnalyzer {
|
|
|
262
261
|
|
|
263
262
|
/**
|
|
264
263
|
* Executes all configured strategies and returns their results.
|
|
265
|
-
* Each strategy
|
|
264
|
+
* Each strategy handles its own RPC calls internally.
|
|
266
265
|
* @param isBlobTx - Whether this is a blob transaction
|
|
267
266
|
* @returns Array of strategy results
|
|
268
267
|
*/
|
|
@@ -276,7 +275,7 @@ export class L1FeeAnalyzer {
|
|
|
276
275
|
|
|
277
276
|
for (const strategy of this.strategies) {
|
|
278
277
|
try {
|
|
279
|
-
const result = await
|
|
278
|
+
const result = await strategy.execute(this.client, context);
|
|
280
279
|
|
|
281
280
|
results.push({
|
|
282
281
|
strategyId: strategy.id,
|