@aztec/ethereum 0.0.1-commit.4d3c002 → 0.0.1-commit.4d9804df
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/client.d.ts +17 -3
- package/dest/client.d.ts.map +1 -1
- package/dest/client.js +49 -3
- package/dest/config.d.ts +27 -8
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +59 -12
- package/dest/contracts/chain_state_override.d.ts +78 -0
- package/dest/contracts/chain_state_override.d.ts.map +1 -0
- package/dest/contracts/chain_state_override.js +137 -0
- package/dest/contracts/empire_base.d.ts +1 -3
- package/dest/contracts/empire_base.d.ts.map +1 -1
- package/dest/contracts/fee_asset_price_oracle.d.ts +6 -2
- package/dest/contracts/fee_asset_price_oracle.d.ts.map +1 -1
- package/dest/contracts/fee_asset_price_oracle.js +11 -6
- package/dest/contracts/governance.d.ts +108 -33
- package/dest/contracts/governance.d.ts.map +1 -1
- package/dest/contracts/governance.js +193 -12
- package/dest/contracts/governance_proposer.d.ts +33 -3
- package/dest/contracts/governance_proposer.d.ts.map +1 -1
- package/dest/contracts/governance_proposer.js +51 -9
- package/dest/contracts/gse.d.ts +4 -2
- package/dest/contracts/gse.d.ts.map +1 -1
- package/dest/contracts/gse.js +2 -2
- package/dest/contracts/inbox.d.ts +3 -3
- package/dest/contracts/inbox.d.ts.map +1 -1
- package/dest/contracts/inbox.js +9 -3
- package/dest/contracts/index.d.ts +3 -3
- package/dest/contracts/index.d.ts.map +1 -1
- package/dest/contracts/index.js +2 -2
- package/dest/contracts/multicall.d.ts +82 -14
- package/dest/contracts/multicall.d.ts.map +1 -1
- package/dest/contracts/multicall.js +119 -95
- package/dest/contracts/outbox.d.ts +27 -4
- package/dest/contracts/outbox.d.ts.map +1 -1
- package/dest/contracts/outbox.js +34 -7
- package/dest/contracts/rollup.d.ts +5383 -31
- package/dest/contracts/rollup.d.ts.map +1 -1
- package/dest/contracts/rollup.js +223 -90
- package/dest/contracts/{tally_slashing_proposer.d.ts → slashing_proposer.d.ts} +3 -4
- package/dest/contracts/slashing_proposer.d.ts.map +1 -0
- package/dest/contracts/{tally_slashing_proposer.js → slashing_proposer.js} +13 -15
- package/dest/deploy_aztec_l1_contracts.d.ts +18 -10
- package/dest/deploy_aztec_l1_contracts.d.ts.map +1 -1
- package/dest/deploy_aztec_l1_contracts.js +28 -17
- package/dest/foundry_binary.d.ts +13 -0
- package/dest/foundry_binary.d.ts.map +1 -0
- package/dest/foundry_binary.js +52 -0
- package/dest/l1_artifacts.d.ts +14941 -16273
- package/dest/l1_artifacts.d.ts.map +1 -1
- package/dest/l1_artifacts.js +9 -24
- package/dest/l1_contract_addresses.d.ts +61 -65
- package/dest/l1_contract_addresses.d.ts.map +1 -1
- package/dest/l1_contract_addresses.js +101 -82
- package/dest/l1_reader.d.ts +3 -5
- package/dest/l1_reader.d.ts.map +1 -1
- package/dest/l1_reader.js +3 -6
- package/dest/l1_tx_utils/config.js +3 -3
- package/dest/l1_tx_utils/l1_fee_analyzer.d.ts +23 -4
- package/dest/l1_tx_utils/l1_fee_analyzer.d.ts.map +1 -1
- package/dest/l1_tx_utils/l1_fee_analyzer.js +65 -3
- package/dest/l1_tx_utils/l1_tx_utils.d.ts +7 -1
- package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -1
- package/dest/l1_tx_utils/l1_tx_utils.js +105 -32
- package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts +1 -1
- package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -1
- package/dest/l1_tx_utils/readonly_l1_tx_utils.js +2 -1
- package/dest/l1_tx_utils/tx_delayer.d.ts +5 -3
- package/dest/l1_tx_utils/tx_delayer.d.ts.map +1 -1
- package/dest/l1_tx_utils/tx_delayer.js +7 -5
- package/dest/l1_tx_utils/types.d.ts +27 -1
- package/dest/l1_tx_utils/types.d.ts.map +1 -1
- package/dest/l1_tx_utils/types.js +10 -0
- package/dest/publisher_manager.d.ts +18 -6
- package/dest/publisher_manager.d.ts.map +1 -1
- package/dest/publisher_manager.js +44 -7
- package/dest/queries.d.ts +13 -2
- package/dest/queries.d.ts.map +1 -1
- package/dest/queries.js +69 -4
- package/dest/test/blob_kzg_warmup.d.ts +19 -0
- package/dest/test/blob_kzg_warmup.d.ts.map +1 -0
- package/dest/test/blob_kzg_warmup.js +64 -0
- package/dest/test/chain_monitor.d.ts +34 -2
- package/dest/test/chain_monitor.d.ts.map +1 -1
- package/dest/test/chain_monitor.js +76 -6
- package/dest/test/eth_cheat_codes.d.ts +32 -3
- package/dest/test/eth_cheat_codes.d.ts.map +1 -1
- package/dest/test/eth_cheat_codes.js +83 -37
- package/dest/test/index.d.ts +2 -1
- package/dest/test/index.d.ts.map +1 -1
- package/dest/test/index.js +1 -0
- package/dest/test/rollup_cheat_codes.d.ts +60 -3
- package/dest/test/rollup_cheat_codes.d.ts.map +1 -1
- package/dest/test/rollup_cheat_codes.js +86 -7
- package/dest/test/start_anvil.d.ts +1 -1
- package/dest/test/start_anvil.d.ts.map +1 -1
- package/dest/test/start_anvil.js +41 -5
- package/dest/utils.d.ts +9 -2
- package/dest/utils.d.ts.map +1 -1
- package/dest/utils.js +34 -6
- package/package.json +6 -7
- package/src/client.ts +57 -1
- package/src/config.ts +82 -16
- package/src/contracts/chain_state_override.ts +200 -0
- package/src/contracts/empire_base.ts +0 -2
- package/src/contracts/fee_asset_price_oracle.ts +10 -5
- package/src/contracts/governance.ts +266 -9
- package/src/contracts/governance_proposer.ts +52 -5
- package/src/contracts/gse.ts +7 -2
- package/src/contracts/inbox.ts +12 -4
- package/src/contracts/index.ts +2 -2
- package/src/contracts/multicall.ts +183 -106
- package/src/contracts/outbox.ts +42 -8
- package/src/contracts/rollup.ts +252 -96
- package/src/contracts/{tally_slashing_proposer.ts → slashing_proposer.ts} +14 -16
- package/src/deploy_aztec_l1_contracts.ts +32 -18
- package/src/foundry_binary.ts +57 -0
- package/src/l1_artifacts.ts +12 -35
- package/src/l1_contract_addresses.ts +120 -94
- package/src/l1_reader.ts +4 -9
- package/src/l1_tx_utils/config.ts +3 -3
- package/src/l1_tx_utils/l1_fee_analyzer.ts +75 -3
- package/src/l1_tx_utils/l1_tx_utils.ts +98 -34
- package/src/l1_tx_utils/readonly_l1_tx_utils.ts +2 -1
- package/src/l1_tx_utils/tx_delayer.ts +16 -7
- package/src/l1_tx_utils/types.ts +32 -0
- package/src/publisher_manager.ts +54 -18
- package/src/queries.ts +76 -4
- package/src/test/blob_kzg_warmup.ts +65 -0
- package/src/test/chain_monitor.ts +93 -5
- package/src/test/eth_cheat_codes.ts +76 -41
- package/src/test/index.ts +1 -0
- package/src/test/rollup_cheat_codes.ts +115 -6
- package/src/test/start_anvil.ts +38 -6
- package/src/utils.ts +30 -6
- package/dest/contracts/empire_slashing_proposer.d.ts +0 -69
- package/dest/contracts/empire_slashing_proposer.d.ts.map +0 -1
- package/dest/contracts/empire_slashing_proposer.js +0 -216
- package/dest/contracts/tally_slashing_proposer.d.ts.map +0 -1
- package/dest/generated/l1-contracts-defaults.d.ts +0 -30
- package/dest/generated/l1-contracts-defaults.d.ts.map +0 -1
- package/dest/generated/l1-contracts-defaults.js +0 -30
- package/src/contracts/empire_slashing_proposer.ts +0 -265
- package/src/generated/l1-contracts-defaults.ts +0 -32
|
@@ -3,7 +3,7 @@ import { merge, pick } from '@aztec/foundation/collection';
|
|
|
3
3
|
import { InterruptError, TimeoutError } from '@aztec/foundation/error';
|
|
4
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
5
5
|
import { Semaphore } from '@aztec/foundation/queue';
|
|
6
|
-
import { retryUntil } from '@aztec/foundation/retry';
|
|
6
|
+
import { makeBackoff, retry, retryUntil } from '@aztec/foundation/retry';
|
|
7
7
|
import { sleep } from '@aztec/foundation/sleep';
|
|
8
8
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
9
9
|
import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
|
|
@@ -14,8 +14,17 @@ import { l1TxUtilsConfigMappings } from './config.js';
|
|
|
14
14
|
import { MAX_L1_TX_LIMIT } from './constants.js';
|
|
15
15
|
import { ReadOnlyL1TxUtils } from './readonly_l1_tx_utils.js';
|
|
16
16
|
import { createDelayer, wrapClientWithDelayer } from './tx_delayer.js';
|
|
17
|
-
import { DroppedTransactionError, TerminalTxUtilsState, TxUtilsState, UnknownMinedTxError } from './types.js';
|
|
17
|
+
import { DroppedTransactionError, L1TxTimeoutError, TerminalTxUtilsState, TxUtilsState, UnknownMinedTxError } from './types.js';
|
|
18
18
|
const MAX_L1_TX_STATES = 32;
|
|
19
|
+
// Backoff (in seconds) for retrying the read-only RPC calls that prepare a tx cancellation. A
|
|
20
|
+
// cancellation is fired in the background after a tx times out and is important (it frees the stuck
|
|
21
|
+
// nonce), so a transient RPC failure while reading the pending nonce or gas price must not abandon it.
|
|
22
|
+
const CANCELLATION_PREP_RETRY_BACKOFF_S = [
|
|
23
|
+
1,
|
|
24
|
+
2,
|
|
25
|
+
4,
|
|
26
|
+
8
|
|
27
|
+
];
|
|
19
28
|
export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
20
29
|
client;
|
|
21
30
|
address;
|
|
@@ -75,6 +84,12 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
75
84
|
this.config = merge(this.config, newConfig);
|
|
76
85
|
this.logger.info('Updated L1TxUtils config', pickBy(newConfig, (_, key)=>key in l1TxUtilsConfigMappings));
|
|
77
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Clears the cached `lastSentNonce` so the next `sendTransaction` call fetches the real
|
|
89
|
+
* nonce from the chain. Call this after an L1 reorg to prevent stale nonce references.
|
|
90
|
+
*/ resetNonce() {
|
|
91
|
+
this.lastSentNonce = undefined;
|
|
92
|
+
}
|
|
78
93
|
getSenderAddress() {
|
|
79
94
|
return this.address;
|
|
80
95
|
}
|
|
@@ -141,18 +156,29 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
141
156
|
const txRequest = await this.client.prepareTransactionRequest(txData);
|
|
142
157
|
return await this.signTransaction(txRequest);
|
|
143
158
|
}
|
|
159
|
+
async checkInterruptedOrTimedOut(gasConfig) {
|
|
160
|
+
if (this.interrupted) {
|
|
161
|
+
throw new InterruptError(`Transaction sending is interrupted`);
|
|
162
|
+
}
|
|
163
|
+
const now = new Date(await this.getL1Timestamp());
|
|
164
|
+
if (gasConfig.txTimeoutAt && now > gasConfig.txTimeoutAt) {
|
|
165
|
+
throw new TimeoutError(`Transaction timed out before sending (now ${now.toISOString()} > timeoutAt ${gasConfig.txTimeoutAt.toISOString()})`);
|
|
166
|
+
}
|
|
167
|
+
return now;
|
|
168
|
+
}
|
|
144
169
|
/**
|
|
145
170
|
* Sends a transaction with gas estimation and pricing
|
|
146
171
|
* @param request - The transaction request (to, data, value)
|
|
147
172
|
* @param gasConfig - Optional gas configuration
|
|
148
173
|
* @returns The transaction hash and parameters used
|
|
149
174
|
*/ async sendTransaction(request, gasConfigOverrides, blobInputs, stateChange = TxUtilsState.SENT) {
|
|
150
|
-
if (this.interrupted) {
|
|
151
|
-
throw new InterruptError(`Transaction sending is interrupted`);
|
|
152
|
-
}
|
|
153
175
|
try {
|
|
154
176
|
const gasConfig = merge(this.config, gasConfigOverrides);
|
|
155
177
|
const account = this.getSenderAddress().toString();
|
|
178
|
+
// Fail fast before doing any work (gas estimation, balance check) if we've been interrupted
|
|
179
|
+
// or if the caller's deadline has already passed. The same check is repeated after gas
|
|
180
|
+
// estimation in case it took long enough to push us past the deadline.
|
|
181
|
+
await this.checkInterruptedOrTimedOut(gasConfig);
|
|
156
182
|
let gasLimit;
|
|
157
183
|
if (this.debugMaxGasLimit) {
|
|
158
184
|
gasLimit = MAX_L1_TX_LIMIT;
|
|
@@ -166,13 +192,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
166
192
|
...request
|
|
167
193
|
});
|
|
168
194
|
const gasPrice = await this.getGasPrice(gasConfig, !!blobInputs);
|
|
169
|
-
|
|
170
|
-
throw new InterruptError(`Transaction sending is interrupted`);
|
|
171
|
-
}
|
|
172
|
-
const now = new Date(await this.getL1Timestamp());
|
|
173
|
-
if (gasConfig.txTimeoutAt && now > gasConfig.txTimeoutAt) {
|
|
174
|
-
throw new TimeoutError(`Transaction timed out before sending (now ${now.toISOString()} > timeoutAt ${gasConfig.txTimeoutAt.toISOString()})`);
|
|
175
|
-
}
|
|
195
|
+
const now = await this.checkInterruptedOrTimedOut(gasConfig);
|
|
176
196
|
let txHash;
|
|
177
197
|
let nonce;
|
|
178
198
|
let baseState;
|
|
@@ -214,7 +234,10 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
214
234
|
status: TxUtilsState.IDLE,
|
|
215
235
|
txConfigOverrides: gasConfigOverrides ?? {},
|
|
216
236
|
sentAtL1Ts: now,
|
|
217
|
-
lastSentAtL1Ts: now
|
|
237
|
+
lastSentAtL1Ts: now,
|
|
238
|
+
gasPriceHistory: [
|
|
239
|
+
baseState.gasPrice
|
|
240
|
+
]
|
|
218
241
|
};
|
|
219
242
|
// And persist it
|
|
220
243
|
await this.updateState(l1TxState, stateChange);
|
|
@@ -338,9 +361,25 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
338
361
|
const account = this.getSenderAddress().toString();
|
|
339
362
|
const initialTxHash = txHashes[0];
|
|
340
363
|
let currentTxHash = txHashes.at(-1);
|
|
341
|
-
let l1Timestamp;
|
|
364
|
+
let l1Timestamp = 0;
|
|
342
365
|
while(true){
|
|
343
|
-
|
|
366
|
+
try {
|
|
367
|
+
l1Timestamp = await this.getL1Timestamp();
|
|
368
|
+
} catch (err) {
|
|
369
|
+
// A transient RPC failure here must not abort monitoring with a rejection: callers that
|
|
370
|
+
// fire this loop in the background would surface it as an unhandled rejection (e.g. when a
|
|
371
|
+
// test tears down its L1 node while a monitor iteration is in flight). Exit quietly if we
|
|
372
|
+
// are shutting down, otherwise retry on the next interval.
|
|
373
|
+
if (this.interrupted) {
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
376
|
+
this.logger.error(`Error fetching L1 timestamp while monitoring tx ${currentTxHash}`, err, {
|
|
377
|
+
nonce,
|
|
378
|
+
account
|
|
379
|
+
});
|
|
380
|
+
await sleep(gasConfig.checkIntervalMs);
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
344
383
|
try {
|
|
345
384
|
const timePassed = l1Timestamp - state.lastSentAtL1Ts.getTime();
|
|
346
385
|
const [currentNonce, pendingNonce] = await Promise.all([
|
|
@@ -388,6 +427,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
388
427
|
if (timePassed >= stallTimeMs && attempts <= maxSpeedUpAttempts) {
|
|
389
428
|
const newGasPrice = await this.getGasPrice(gasConfig, isBlobTx, attempts, state.gasPrice);
|
|
390
429
|
state.gasPrice = newGasPrice;
|
|
430
|
+
state.gasPriceHistory?.push(newGasPrice);
|
|
391
431
|
this.logger.debug(`Tx ${currentTxHash} with nonce ${nonce} from ${account} appears stuck. ` + `Attempting speed-up ${attempts}/${maxSpeedUpAttempts} ` + `with new priority fee ${formatGwei(newGasPrice.maxPriorityFeePerGas)} gwei.`, {
|
|
392
432
|
account,
|
|
393
433
|
nonce,
|
|
@@ -523,11 +563,27 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
523
563
|
* @returns The receipt of the successful transaction
|
|
524
564
|
*/ async sendAndMonitorTransaction(request, gasConfig, blobInputs) {
|
|
525
565
|
const { state } = await this.sendTransaction(request, gasConfig, blobInputs);
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
566
|
+
try {
|
|
567
|
+
const receipt = await this.monitorTransaction(state);
|
|
568
|
+
return {
|
|
569
|
+
receipt,
|
|
570
|
+
state
|
|
571
|
+
};
|
|
572
|
+
} catch (err) {
|
|
573
|
+
if (err instanceof TimeoutError) {
|
|
574
|
+
// Snapshot the ladder now: the fire-and-forget cancellation mutates state.gasPrice moments later.
|
|
575
|
+
throw new L1TxTimeoutError(err.message, {
|
|
576
|
+
gasPriceHistory: state.gasPriceHistory ? [
|
|
577
|
+
...state.gasPriceHistory
|
|
578
|
+
] : undefined,
|
|
579
|
+
finalGasPrice: state.gasPrice,
|
|
580
|
+
attempts: state.txHashes.length,
|
|
581
|
+
nonce: state.nonce,
|
|
582
|
+
gasLimit: state.gasLimit
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
throw err;
|
|
586
|
+
}
|
|
531
587
|
}
|
|
532
588
|
async simulate(request, _blockOverrides = {}, stateOverrides = [], abi = RollupAbi, _gasConfig) {
|
|
533
589
|
const blockOverrides = {
|
|
@@ -566,12 +622,35 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
566
622
|
await this.updateState(state, TxUtilsState.NOT_MINED);
|
|
567
623
|
return;
|
|
568
624
|
}
|
|
569
|
-
//
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
625
|
+
// Resolve the pending nonce and cancellation gas price up front. These are read-only RPC calls, so
|
|
626
|
+
// they are safe to retry; a transient RPC failure here must not permanently abandon the cancellation
|
|
627
|
+
// (which would leave the nonce stuck and the tx state stranded short of CANCELLED). We retry with a
|
|
628
|
+
// real backoff before giving up, unlike getGasPrice's tight internal retry which can be exhausted by
|
|
629
|
+
// a brief node hiccup. The retried block performs no state-changing send, so retrying cannot
|
|
630
|
+
// double-send the cancellation tx.
|
|
631
|
+
const { currentNonce, cancelGasPrice } = await retry(async ()=>{
|
|
632
|
+
const currentNonce = await this.client.getTransactionCount({
|
|
633
|
+
address: account,
|
|
634
|
+
blockTag: 'pending'
|
|
635
|
+
});
|
|
636
|
+
if (currentNonce >= nonce) {
|
|
637
|
+
// Get gas price with higher priority fee for cancellation
|
|
638
|
+
const cancelGasPrice = await this.getGasPrice({
|
|
639
|
+
...this.config,
|
|
640
|
+
// Use high bump for cancellation to ensure it replaces the original tx
|
|
641
|
+
priorityFeeRetryBumpPercentage: 150
|
|
642
|
+
}, isBlobTx, state.txHashes.length, previousGasPrice);
|
|
643
|
+
return {
|
|
644
|
+
currentNonce,
|
|
645
|
+
cancelGasPrice
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
return {
|
|
649
|
+
currentNonce,
|
|
650
|
+
cancelGasPrice: undefined
|
|
651
|
+
};
|
|
652
|
+
}, `Preparing cancellation for L1 tx from account ${account} with nonce ${nonce}`, makeBackoff(CANCELLATION_PREP_RETRY_BACKOFF_S), this.logger);
|
|
653
|
+
if (cancelGasPrice === undefined) {
|
|
575
654
|
this.logger.verbose(`Not sending cancellation for L1 tx from account ${account} with nonce ${nonce} as it is dropped`, {
|
|
576
655
|
nonce,
|
|
577
656
|
account,
|
|
@@ -580,12 +659,6 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
580
659
|
await this.updateState(state, TxUtilsState.NOT_MINED);
|
|
581
660
|
return;
|
|
582
661
|
}
|
|
583
|
-
// Get gas price with higher priority fee for cancellation
|
|
584
|
-
const cancelGasPrice = await this.getGasPrice({
|
|
585
|
-
...this.config,
|
|
586
|
-
// Use high bump for cancellation to ensure it replaces the original tx
|
|
587
|
-
priorityFeeRetryBumpPercentage: 150
|
|
588
|
-
}, isBlobTx, state.txHashes.length, previousGasPrice);
|
|
589
662
|
const { maxFeePerGas, maxPriorityFeePerGas, maxFeePerBlobGas } = cancelGasPrice;
|
|
590
663
|
this.logger.verbose(`Attempting to cancel L1 ${isBlobTx ? 'blob' : 'vanilla'} transaction from account ${account} with nonce ${nonce} after time out`, {
|
|
591
664
|
maxFeePerGas: formatGwei(maxFeePerGas),
|
|
@@ -80,4 +80,4 @@ export declare class ReadOnlyL1TxUtils {
|
|
|
80
80
|
}>;
|
|
81
81
|
bumpGasLimit(gasLimit: bigint, _gasConfig?: L1TxUtilsConfig): bigint;
|
|
82
82
|
}
|
|
83
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
83
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhZG9ubHlfbDFfdHhfdXRpbHMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9sMV90eF91dGlscy9yZWFkb25seV9sMV90eF91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNoRSxPQUFPLEVBQUUsS0FBSyxNQUFNLEVBQWdCLE1BQU0sdUJBQXVCLENBQUM7QUFFbEUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBS3ZELE9BQU8sRUFDTCxLQUFLLEdBQUcsRUFDUixLQUFLLE9BQU8sRUFFWixLQUFLLGNBQWMsRUFFbkIsS0FBSyxpQkFBaUIsRUFDdEIsS0FBSyxHQUFHLEVBR1IsS0FBSyxhQUFhLEVBS25CLE1BQU0sTUFBTSxDQUFDO0FBRWQsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzlDLE9BQU8sRUFBRSxLQUFLLGVBQWUsRUFBbUQsTUFBTSxhQUFhLENBQUM7QUFTcEcsT0FBTyxLQUFLLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFNeEYscUJBQWEsaUJBQWlCO0lBS25CLE1BQU0sRUFBRSxVQUFVO0lBQ3pCLFNBQVMsQ0FBQyxNQUFNLEVBQUUsTUFBTTthQUNSLFlBQVksRUFBRSxZQUFZO0lBRTFDLFNBQVMsQ0FBQyxnQkFBZ0IsRUFBRSxPQUFPO0lBUjlCLE1BQU0sRUFBRSxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDekMsU0FBUyxDQUFDLFdBQVcsVUFBUztJQUU5QixZQUNTLE1BQU0sRUFBRSxVQUFVLEVBQ2YsTUFBTSxvQkFBcUQsRUFDckQsWUFBWSxFQUFFLFlBQVksRUFDMUMsTUFBTSxDQUFDLEVBQUUsT0FBTyxDQUFDLGVBQWUsQ0FBQyxFQUN2QixnQkFBZ0IsR0FBRSxPQUFlLEVBRzVDO0lBRU0sU0FBUyxTQUVmO0lBRU0sT0FBTyxTQUViO0lBRU0sUUFBUTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQUVkO0lBRU0sY0FBYyxvQkFFcEI7SUFFTSxPQUFPLENBQUMsT0FBTyxFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FFOUQ7SUFFRDs7T0FFRztJQUNVLFdBQVcsQ0FDdEIsa0JBQWtCLENBQUMsRUFBRSxlQUFlLEVBQ3BDLFFBQVEsR0FBRSxPQUFlLEVBQ3pCLE9BQU8sR0FBRSxNQUFVLEVBQ25CLGdCQUFnQixDQUFDLEVBQUUsT0FBTyxPQUFPLFNBQVMsQ0FBQyxHQUFHLEtBQUssR0FBRyxRQUFRLEdBQzdELE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FvSm5CO0lBRUQ7O09BRUc7SUFDVSxXQUFXLENBQ3RCLE9BQU8sRUFBRSxPQUFPLEdBQUcsR0FBRyxFQUN0QixPQUFPLEVBQUUsV0FBVyxFQUNwQixVQUFVLENBQUMsRUFBRSxlQUFlLEVBQzVCLFdBQVcsQ0FBQyxFQUFFLFlBQVksR0FDekIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQWlDakI7SUFFSyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsR0FBRyxTQUFTLENBQUMsQ0FZL0U7SUFFWSx5QkFBeUIsQ0FDcEMsSUFBSSxFQUFFLEdBQUcsRUFDVCxJQUFJLEVBQUU7UUFDSixJQUFJLEVBQUUsU0FBUyxHQUFHLEVBQUUsQ0FBQztRQUNyQixZQUFZLEVBQUUsTUFBTSxDQUFDO1FBQ3JCLEdBQUcsRUFBRSxHQUFHLENBQUM7UUFDVCxPQUFPLEVBQUUsR0FBRyxDQUFDO0tBQ2QsRUFDRCxVQUFVLEVBQUUsQ0FBQyxZQUFZLEdBQUc7UUFBRSxnQkFBZ0IsRUFBRSxNQUFNLENBQUE7S0FBRSxDQUFDLEdBQUcsU0FBUyxFQUNyRSxhQUFhLEdBQUUsYUFBa0IsK0JBZ0RsQztJQUVZLFFBQVEsQ0FDbkIsT0FBTyxFQUFFLFdBQVcsR0FBRztRQUFFLEdBQUcsQ0FBQyxFQUFFLE1BQU0sQ0FBQztRQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQTtLQUFFLEVBQ25ELGNBQWMsR0FBRSxjQUFjLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBTSxFQUNuRCxjQUFjLEdBQUUsYUFBa0IsRUFDbEMsR0FBRyxHQUFFLEdBQWUsRUFDcEIsVUFBVSxDQUFDLEVBQUUsZUFBZSxHQUFHO1FBQUUsbUJBQW1CLENBQUMsRUFBRSxNQUFNLENBQUE7S0FBRSxHQUM5RCxPQUFPLENBQUM7UUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDO1FBQUMsTUFBTSxFQUFFLEtBQUssTUFBTSxFQUFFLENBQUE7S0FBRSxDQUFDLENBVXJEO0lBRUQsVUFBZ0IsU0FBUyxDQUN2QixJQUFJLEVBQUUsR0FBRyxFQUNULGNBQWMsNENBQXFDLEVBQ25ELGNBQWMsMkJBQW9CLEVBQ2xDLFNBQVMsRUFBRSxlQUFlLEdBQUc7UUFBRSxtQkFBbUIsQ0FBQyxFQUFFLE1BQU0sQ0FBQTtLQUFFLEVBQzdELEdBQUcsRUFBRSxHQUFHOzs7T0FvQ1Q7SUFFTSxZQUFZLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxVQUFVLENBQUMsRUFBRSxlQUFlLEdBQUcsTUFBTSxDQVcxRTtDQUNGIn0=
|
|
@@ -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,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAElE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,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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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getKeys, merge, pick, times } from '@aztec/foundation/collection';
|
|
2
2
|
import { createLogger } from '@aztec/foundation/log';
|
|
3
3
|
import { makeBackoff, retry } from '@aztec/foundation/retry';
|
|
4
|
+
import { getErrorCause } from '@aztec/foundation/types';
|
|
4
5
|
import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
|
|
5
6
|
import pickBy from 'lodash.pickby';
|
|
6
7
|
import { MethodNotFoundRpcError, MethodNotSupportedRpcError, decodeErrorResult, formatGwei, getContractError, hexToBytes } from 'viem';
|
|
@@ -297,7 +298,7 @@ export class ReadOnlyL1TxUtils {
|
|
|
297
298
|
result: result[0].calls[0].data
|
|
298
299
|
};
|
|
299
300
|
} catch (err) {
|
|
300
|
-
if (err
|
|
301
|
+
if (getErrorCause(err, MethodNotFoundRpcError) || getErrorCause(err, MethodNotSupportedRpcError)) {
|
|
301
302
|
if (gasConfig.fallbackGasEstimate) {
|
|
302
303
|
this.logger?.warn(`Node does not support eth_simulateV1 API. Using fallback gas estimate: ${gasConfig.fallbackGasEstimate}`);
|
|
303
304
|
return {
|
|
@@ -12,8 +12,10 @@ export declare class Delayer {
|
|
|
12
12
|
ethereumSlotDuration: bigint;
|
|
13
13
|
nextWait: {
|
|
14
14
|
l1Timestamp: bigint;
|
|
15
|
+
timeoutSeconds?: number;
|
|
15
16
|
} | {
|
|
16
17
|
l1BlockNumber: bigint;
|
|
18
|
+
timeoutSeconds?: number;
|
|
17
19
|
} | {
|
|
18
20
|
indefinitely: true;
|
|
19
21
|
} | undefined;
|
|
@@ -29,9 +31,9 @@ export declare class Delayer {
|
|
|
29
31
|
/** Returns the raw hex for all cancelled txs. */
|
|
30
32
|
getCancelledTxs(): Hex[];
|
|
31
33
|
/** Delays the next tx to be sent so it lands on the given L1 block number. */
|
|
32
|
-
pauseNextTxUntilBlock(l1BlockNumber: number | bigint): void;
|
|
34
|
+
pauseNextTxUntilBlock(l1BlockNumber: number | bigint, timeoutSeconds?: number): void;
|
|
33
35
|
/** Delays the next tx to be sent so it lands on the given timestamp. */
|
|
34
|
-
pauseNextTxUntilTimestamp(l1Timestamp: number | bigint): void;
|
|
36
|
+
pauseNextTxUntilTimestamp(l1Timestamp: number | bigint, timeoutSeconds?: number): void;
|
|
35
37
|
/** Delays the next tx to be sent indefinitely. */
|
|
36
38
|
cancelNextTx(): void;
|
|
37
39
|
/**
|
|
@@ -53,4 +55,4 @@ export declare function createDelayer(dateProvider: DateProvider, opts: {
|
|
|
53
55
|
* The delayer intercepts sendRawTransaction calls and delays them based on the delayer's state.
|
|
54
56
|
*/
|
|
55
57
|
export declare function wrapClientWithDelayer<T extends ViemClient>(client: T, delayer: Delayer): T;
|
|
56
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
58
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhfZGVsYXllci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2wxX3R4X3V0aWxzL3R4X2RlbGF5ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLEtBQUssTUFBTSxFQUFFLEtBQUssY0FBYyxFQUFnQixNQUFNLHVCQUF1QixDQUFDO0FBRXZGLE9BQU8sS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRzVELE9BQU8sRUFDTCxLQUFLLE1BQU0sRUFDWCxLQUFLLEdBQUcsRUFVVCxNQUFNLE1BQU0sQ0FBQztBQUVkLE9BQU8sS0FBSyxFQUE0QixVQUFVLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFJeEUsd0JBQWdCLGNBQWMsQ0FBQyxDQUFDLFNBQVMsTUFBTSxFQUM3QyxNQUFNLEVBQUUsQ0FBQyxFQUNULFdBQVcsRUFBRSxNQUFNLEdBQUcsTUFBTSxFQUM1QixNQUFNLENBQUMsRUFBRSxNQUFNLEVBQ2YsT0FBTyxDQUFDLEVBQUUsTUFBTSxvQkFpQmpCO0FBRUQsd0JBQWdCLG9CQUFvQixDQUFDLENBQUMsU0FBUyxNQUFNLEVBQ25ELE1BQU0sRUFBRSxDQUFDLEVBQ1QsU0FBUyxFQUFFLE1BQU0sR0FBRyxNQUFNLEVBQzFCLE1BQU0sQ0FBQyxFQUFFLE1BQU0sRUFDZixPQUFPLENBQUMsRUFBRSxNQUFNLG9CQXdCakI7QUFFRCxzR0FBc0c7QUFDdEcscUJBQWEsT0FBTztJQWNULFlBQVksRUFBRSxZQUFZO0lBYm5DLE9BQU8sQ0FBQyxNQUFNLENBQVM7SUFFaEIsd0JBQXdCLEVBQUUsTUFBTSxHQUFHLFNBQVMsQ0FBYTtJQUN6RCxvQkFBb0IsRUFBRSxNQUFNLENBQUM7SUFDN0IsUUFBUSxFQUNYO1FBQUUsV0FBVyxFQUFFLE1BQU0sQ0FBQztRQUFDLGNBQWMsQ0FBQyxFQUFFLE1BQU0sQ0FBQTtLQUFFLEdBQ2hEO1FBQUUsYUFBYSxFQUFFLE1BQU0sQ0FBQztRQUFDLGNBQWMsQ0FBQyxFQUFFLE1BQU0sQ0FBQTtLQUFFLEdBQ2xEO1FBQUUsWUFBWSxFQUFFLElBQUksQ0FBQTtLQUFFLEdBQ3RCLFNBQVMsQ0FBYTtJQUNuQixZQUFZLEVBQUUsR0FBRyxFQUFFLENBQU07SUFDekIsWUFBWSxFQUFFLEdBQUcsRUFBRSxDQUFNO0lBRWhDLFlBQ1MsWUFBWSxFQUFFLFlBQVksRUFDakMsSUFBSSxFQUFFO1FBQUUsb0JBQW9CLEVBQUUsTUFBTSxHQUFHLE1BQU0sQ0FBQTtLQUFFLEVBQy9DLFFBQVEsRUFBRSxjQUFjLEVBSXpCO0lBRUQsd0RBQXdEO0lBQ3hELFNBQVMsSUFBSSxNQUFNLENBRWxCO0lBRUQsc0RBQXNEO0lBQ3RELGVBQWUsb0JBRWQ7SUFFRCxpREFBaUQ7SUFDakQsZUFBZSxJQUFJLEdBQUcsRUFBRSxDQUV2QjtJQUVELDhFQUE4RTtJQUM5RSxxQkFBcUIsQ0FBQyxhQUFhLEVBQUUsTUFBTSxHQUFHLE1BQU0sRUFBRSxjQUFjLENBQUMsRUFBRSxNQUFNLFFBRTVFO0lBRUQsd0VBQXdFO0lBQ3hFLHlCQUF5QixDQUFDLFdBQVcsRUFBRSxNQUFNLEdBQUcsTUFBTSxFQUFFLGNBQWMsQ0FBQyxFQUFFLE1BQU0sUUFFOUU7SUFFRCxrREFBa0Q7SUFDbEQsWUFBWSxTQUVYO0lBRUQ7Ozs7T0FJRztJQUNILDJCQUEyQixDQUFDLE9BQU8sRUFBRSxNQUFNLEdBQUcsU0FBUyxRQUV0RDtDQUNGO0FBRUQ7OztHQUdHO0FBQ0gsd0JBQWdCLGFBQWEsQ0FDM0IsWUFBWSxFQUFFLFlBQVksRUFDMUIsSUFBSSxFQUFFO0lBQUUsb0JBQW9CLEVBQUUsTUFBTSxHQUFHLE1BQU0sQ0FBQTtDQUFFLEVBQy9DLFFBQVEsRUFBRSxjQUFjLEdBQ3ZCLE9BQU8sQ0FFVDtBQWFEOzs7R0FHRztBQUNILHdCQUFnQixxQkFBcUIsQ0FBQyxDQUFDLFNBQVMsVUFBVSxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLE9BQU8sR0FBRyxDQUFDLENBdUgxRiJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tx_delayer.d.ts","sourceRoot":"","sources":["../../src/l1_tx_utils/tx_delayer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,cAAc,EAAgB,MAAM,uBAAuB,CAAC;AAEvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAG5D,OAAO,EACL,KAAK,MAAM,EACX,KAAK,GAAG,EAUT,MAAM,MAAM,CAAC;AAEd,OAAO,KAAK,EAA4B,UAAU,EAAE,MAAM,aAAa,CAAC;AAIxE,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAC7C,MAAM,EAAE,CAAC,EACT,WAAW,EAAE,MAAM,GAAG,MAAM,EAC5B,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,oBAiBjB;AAED,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,EACnD,MAAM,EAAE,CAAC,EACT,SAAS,EAAE,MAAM,GAAG,MAAM,EAC1B,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,oBAwBjB;AAED,sGAAsG;AACtG,qBAAa,OAAO;
|
|
1
|
+
{"version":3,"file":"tx_delayer.d.ts","sourceRoot":"","sources":["../../src/l1_tx_utils/tx_delayer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,cAAc,EAAgB,MAAM,uBAAuB,CAAC;AAEvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAG5D,OAAO,EACL,KAAK,MAAM,EACX,KAAK,GAAG,EAUT,MAAM,MAAM,CAAC;AAEd,OAAO,KAAK,EAA4B,UAAU,EAAE,MAAM,aAAa,CAAC;AAIxE,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAC7C,MAAM,EAAE,CAAC,EACT,WAAW,EAAE,MAAM,GAAG,MAAM,EAC5B,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,oBAiBjB;AAED,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,EACnD,MAAM,EAAE,CAAC,EACT,SAAS,EAAE,MAAM,GAAG,MAAM,EAC1B,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,oBAwBjB;AAED,sGAAsG;AACtG,qBAAa,OAAO;IAcT,YAAY,EAAE,YAAY;IAbnC,OAAO,CAAC,MAAM,CAAS;IAEhB,wBAAwB,EAAE,MAAM,GAAG,SAAS,CAAa;IACzD,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EACX;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GAChD;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GAClD;QAAE,YAAY,EAAE,IAAI,CAAA;KAAE,GACtB,SAAS,CAAa;IACnB,YAAY,EAAE,GAAG,EAAE,CAAM;IACzB,YAAY,EAAE,GAAG,EAAE,CAAM;IAEhC,YACS,YAAY,EAAE,YAAY,EACjC,IAAI,EAAE;QAAE,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,EAC/C,QAAQ,EAAE,cAAc,EAIzB;IAED,wDAAwD;IACxD,SAAS,IAAI,MAAM,CAElB;IAED,sDAAsD;IACtD,eAAe,oBAEd;IAED,iDAAiD;IACjD,eAAe,IAAI,GAAG,EAAE,CAEvB;IAED,8EAA8E;IAC9E,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,QAE5E;IAED,wEAAwE;IACxE,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,QAE9E;IAED,kDAAkD;IAClD,YAAY,SAEX;IAED;;;;OAIG;IACH,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,QAEtD;CACF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,YAAY,EAAE,YAAY,EAC1B,IAAI,EAAE;IAAE,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,EAC/C,QAAQ,EAAE,cAAc,GACvB,OAAO,CAET;AAaD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,CAAC,CAuH1F"}
|
|
@@ -60,14 +60,16 @@ export function waitUntilL1Timestamp(client, timestamp, logger, timeout) {
|
|
|
60
60
|
/** Returns the raw hex for all cancelled txs. */ getCancelledTxs() {
|
|
61
61
|
return this.cancelledTxs;
|
|
62
62
|
}
|
|
63
|
-
/** Delays the next tx to be sent so it lands on the given L1 block number. */ pauseNextTxUntilBlock(l1BlockNumber) {
|
|
63
|
+
/** Delays the next tx to be sent so it lands on the given L1 block number. */ pauseNextTxUntilBlock(l1BlockNumber, timeoutSeconds) {
|
|
64
64
|
this.nextWait = {
|
|
65
|
-
l1BlockNumber: BigInt(l1BlockNumber)
|
|
65
|
+
l1BlockNumber: BigInt(l1BlockNumber),
|
|
66
|
+
timeoutSeconds
|
|
66
67
|
};
|
|
67
68
|
}
|
|
68
|
-
/** Delays the next tx to be sent so it lands on the given timestamp. */ pauseNextTxUntilTimestamp(l1Timestamp) {
|
|
69
|
+
/** Delays the next tx to be sent so it lands on the given timestamp. */ pauseNextTxUntilTimestamp(l1Timestamp, timeoutSeconds) {
|
|
69
70
|
this.nextWait = {
|
|
70
|
-
l1Timestamp: BigInt(l1Timestamp)
|
|
71
|
+
l1Timestamp: BigInt(l1Timestamp),
|
|
72
|
+
timeoutSeconds
|
|
71
73
|
};
|
|
72
74
|
}
|
|
73
75
|
/** Delays the next tx to be sent indefinitely. */ cancelNextTx() {
|
|
@@ -131,7 +133,7 @@ export function waitUntilL1Timestamp(client, timestamp, logger, timeout) {
|
|
|
131
133
|
return Promise.resolve(txHash);
|
|
132
134
|
}
|
|
133
135
|
// Or wait until the desired block number or timestamp
|
|
134
|
-
wait = 'l1BlockNumber' in waitUntil ? waitUntilBlock(publicClient, waitUntil.l1BlockNumber - 1n, logger) : 'l1Timestamp' in waitUntil ? waitUntilL1Timestamp(publicClient, waitUntil.l1Timestamp - delayer.ethereumSlotDuration, logger) : undefined;
|
|
136
|
+
wait = 'l1BlockNumber' in waitUntil ? waitUntilBlock(publicClient, waitUntil.l1BlockNumber - 1n, logger, waitUntil.timeoutSeconds) : 'l1Timestamp' in waitUntil ? waitUntilL1Timestamp(publicClient, waitUntil.l1Timestamp - delayer.ethereumSlotDuration, logger, waitUntil.timeoutSeconds) : undefined;
|
|
135
137
|
logger.info(`Delaying tx ${txHash} until ${inspect(waitUntil)}`, {
|
|
136
138
|
sender,
|
|
137
139
|
argsLen: args.length,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BlobKzgInstance } from '@aztec/blob-lib/types';
|
|
2
|
+
import { TimeoutError } from '@aztec/foundation/error';
|
|
2
3
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
4
|
import type { ViemTransactionSignature } from '@aztec/foundation/eth-signature';
|
|
4
5
|
import type { Abi, Address, Hex, TransactionReceipt, TransactionSerializable } from 'viem';
|
|
@@ -48,6 +49,12 @@ export type L1TxState = {
|
|
|
48
49
|
cancelTxHashes: Hex[];
|
|
49
50
|
gasLimit: bigint;
|
|
50
51
|
gasPrice: GasPrice;
|
|
52
|
+
/**
|
|
53
|
+
* Prices used for each attempt (initial send followed by each speed-up), in order. Always set on
|
|
54
|
+
* newly sent txs; optional because states restored from the state store predate the field.
|
|
55
|
+
* In-memory only — not persisted by the state store.
|
|
56
|
+
*/
|
|
57
|
+
gasPriceHistory?: GasPrice[];
|
|
51
58
|
txConfigOverrides: L1TxConfig;
|
|
52
59
|
request: L1TxRequest;
|
|
53
60
|
status: TxUtilsState;
|
|
@@ -64,4 +71,23 @@ export declare class UnknownMinedTxError extends Error {
|
|
|
64
71
|
export declare class DroppedTransactionError extends Error {
|
|
65
72
|
constructor(nonce: number, account: string);
|
|
66
73
|
}
|
|
67
|
-
|
|
74
|
+
/** Snapshot of what a timed-out L1 tx tried to pay, taken when the timeout is raised. */
|
|
75
|
+
export type TimedOutTxState = {
|
|
76
|
+
/** Prices used across the initial send and each speed-up, in order (undefined only for restored states). */
|
|
77
|
+
gasPriceHistory?: GasPrice[];
|
|
78
|
+
/** The last price the tx was sent at before timing out. */
|
|
79
|
+
finalGasPrice: GasPrice;
|
|
80
|
+
/** Number of send attempts (initial + speed-ups). */
|
|
81
|
+
attempts: number;
|
|
82
|
+
nonce: number;
|
|
83
|
+
gasLimit: bigint;
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Thrown by sendAndMonitorTransaction when a tx times out. Subclasses TimeoutError so existing
|
|
87
|
+
* `instanceof TimeoutError` checks keep working, while carrying the gas-price ladder for diagnostics.
|
|
88
|
+
*/
|
|
89
|
+
export declare class L1TxTimeoutError extends TimeoutError {
|
|
90
|
+
readonly txState: TimedOutTxState;
|
|
91
|
+
constructor(message: string, txState: TimedOutTxState);
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9sMV90eF91dGlscy90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDdkQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzNELE9BQU8sS0FBSyxFQUFFLHdCQUF3QixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFaEYsT0FBTyxLQUFLLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsa0JBQWtCLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFM0YsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRW5ELE1BQU0sV0FBVyxXQUFXO0lBQzFCLEVBQUUsRUFBRSxPQUFPLEdBQUcsSUFBSSxDQUFDO0lBQ25CLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQztJQUNYLEtBQUssQ0FBQyxFQUFFLE1BQU0sQ0FBQztJQUNmLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQztDQUNYO0FBRUQsTUFBTSxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDLEdBQUc7SUFBRSxRQUFRLENBQUMsRUFBRSxNQUFNLENBQUM7SUFBQyxXQUFXLENBQUMsRUFBRSxJQUFJLENBQUE7Q0FBRSxDQUFDO0FBRTlGLE1BQU0sV0FBVyxZQUFZO0lBQzNCLEtBQUssRUFBRSxVQUFVLEVBQUUsQ0FBQztJQUNwQixHQUFHLEVBQUUsZUFBZSxDQUFDO0lBQ3JCLGdCQUFnQixDQUFDLEVBQUUsTUFBTSxDQUFDO0NBQzNCO0FBRUQsTUFBTSxXQUFXLFFBQVE7SUFDdkIsWUFBWSxFQUFFLE1BQU0sQ0FBQztJQUNyQixvQkFBb0IsRUFBRSxNQUFNLENBQUM7SUFDN0IsZ0JBQWdCLENBQUMsRUFBRSxNQUFNLENBQUM7Q0FDM0I7QUFFRCxNQUFNLE1BQU0sZ0JBQWdCLEdBQUc7SUFDN0IsNkJBQTZCO0lBQzdCLE1BQU0sRUFBRSxNQUFNLENBQUM7SUFDZiwrQkFBK0I7SUFDL0IsZUFBZSxFQUFFLE1BQU0sQ0FBQztJQUN4Qix1Q0FBdUM7SUFDdkMsWUFBWSxFQUFFLE1BQU0sQ0FBQztJQUNyQiw0RkFBNEY7SUFDNUYsV0FBVyxFQUFFLE1BQU0sQ0FBQztDQUNyQixDQUFDO0FBRUYsb0JBQVksWUFBWTtJQUN0QixJQUFJLElBQUE7SUFDSixJQUFJLElBQUE7SUFDSixRQUFRLElBQUE7SUFDUixTQUFTLElBQUE7SUFDVCxTQUFTLElBQUE7SUFDVCxLQUFLLElBQUE7Q0FDTjtBQUVELGVBQU8sTUFBTSxvQkFBb0IsZ0JBQWtFLENBQUM7QUFFcEcsTUFBTSxNQUFNLFNBQVMsR0FBRztJQUN0QixFQUFFLEVBQUUsTUFBTSxDQUFDO0lBQ1gsUUFBUSxFQUFFLEdBQUcsRUFBRSxDQUFDO0lBQ2hCLGNBQWMsRUFBRSxHQUFHLEVBQUUsQ0FBQztJQUN0QixRQUFRLEVBQUUsTUFBTSxDQUFDO0lBQ2pCLFFBQVEsRUFBRSxRQUFRLENBQUM7SUFDbkI7Ozs7T0FJRztJQUNILGVBQWUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxDQUFDO0lBQzdCLGlCQUFpQixFQUFFLFVBQVUsQ0FBQztJQUM5QixPQUFPLEVBQUUsV0FBVyxDQUFDO0lBQ3JCLE1BQU0sRUFBRSxZQUFZLENBQUM7SUFDckIsS0FBSyxFQUFFLE1BQU0sQ0FBQztJQUNkLFVBQVUsRUFBRSxJQUFJLENBQUM7SUFDakIsY0FBYyxFQUFFLElBQUksQ0FBQztJQUNyQixPQUFPLENBQUMsRUFBRSxrQkFBa0IsQ0FBQztJQUM3QixVQUFVLEVBQUUsWUFBWSxHQUFHLFNBQVMsQ0FBQztDQUN0QyxDQUFDO0FBRUYsTUFBTSxNQUFNLGVBQWUsR0FBRyxDQUM1QixXQUFXLEVBQUUsdUJBQXVCLEVBQ3BDLGNBQWMsRUFBRSxVQUFVLEtBQ3ZCLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0FBRXZDLHFCQUFhLG1CQUFvQixTQUFRLEtBQUs7SUFDNUMsWUFBWSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBR3pDO0NBQ0Y7QUFFRCxxQkFBYSx1QkFBd0IsU0FBUSxLQUFLO0lBQ2hELFlBQVksS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUd6QztDQUNGO0FBRUQseUZBQXlGO0FBQ3pGLE1BQU0sTUFBTSxlQUFlLEdBQUc7SUFDNUIsNEdBQTRHO0lBQzVHLGVBQWUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxDQUFDO0lBQzdCLDJEQUEyRDtJQUMzRCxhQUFhLEVBQUUsUUFBUSxDQUFDO0lBQ3hCLHFEQUFxRDtJQUNyRCxRQUFRLEVBQUUsTUFBTSxDQUFDO0lBQ2pCLEtBQUssRUFBRSxNQUFNLENBQUM7SUFDZCxRQUFRLEVBQUUsTUFBTSxDQUFDO0NBQ2xCLENBQUM7QUFFRjs7O0dBR0c7QUFDSCxxQkFBYSxnQkFBaUIsU0FBUSxZQUFZO2FBRzlCLE9BQU8sRUFBRSxlQUFlO0lBRjFDLFlBQ0UsT0FBTyxFQUFFLE1BQU0sRUFDQyxPQUFPLEVBQUUsZUFBZSxFQUd6QztDQUNGIn0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/l1_tx_utils/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAEhF,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,MAAM,CAAC;AAE3F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,OAAO,GAAG,IAAI,CAAC;IACnB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,GAAG,CAAC;CACX;AAED,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,eAAe,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAE9F,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,GAAG,EAAE,eAAe,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,QAAQ;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,uCAAuC;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,4FAA4F;IAC5F,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,oBAAY,YAAY;IACtB,IAAI,IAAA;IACJ,IAAI,IAAA;IACJ,QAAQ,IAAA;IACR,SAAS,IAAA;IACT,SAAS,IAAA;IACT,KAAK,IAAA;CACN;AAED,eAAO,MAAM,oBAAoB,gBAAkE,CAAC;AAEpG,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,GAAG,EAAE,CAAC;IAChB,cAAc,EAAE,GAAG,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,iBAAiB,EAAE,UAAU,CAAC;IAC9B,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,IAAI,CAAC;IACjB,cAAc,EAAE,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,UAAU,EAAE,YAAY,GAAG,SAAS,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,CAC5B,WAAW,EAAE,uBAAuB,EACpC,cAAc,EAAE,UAAU,KACvB,OAAO,CAAC,wBAAwB,CAAC,CAAC;AAEvC,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAGzC;CACF;AAED,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,YAAY,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAGzC;CACF"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/l1_tx_utils/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TimeoutError } from '@aztec/foundation/error';
|
|
1
2
|
export var TxUtilsState = /*#__PURE__*/ function(TxUtilsState) {
|
|
2
3
|
TxUtilsState[TxUtilsState["IDLE"] = 0] = "IDLE";
|
|
3
4
|
TxUtilsState[TxUtilsState["SENT"] = 1] = "SENT";
|
|
@@ -24,3 +25,12 @@ export class DroppedTransactionError extends Error {
|
|
|
24
25
|
this.name = 'DroppedTransactionError';
|
|
25
26
|
}
|
|
26
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Thrown by sendAndMonitorTransaction when a tx times out. Subclasses TimeoutError so existing
|
|
30
|
+
* `instanceof TimeoutError` checks keep working, while carrying the gas-price ladder for diagnostics.
|
|
31
|
+
*/ export class L1TxTimeoutError extends TimeoutError {
|
|
32
|
+
txState;
|
|
33
|
+
constructor(message, txState){
|
|
34
|
+
super(message), this.txState = txState;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type LoggerBindings } from '@aztec/foundation/log';
|
|
2
|
+
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
2
3
|
import { L1TxUtils } from './l1_tx_utils/index.js';
|
|
3
4
|
export type PublisherFilter<UtilsType extends L1TxUtils> = (utils: UtilsType) => boolean;
|
|
4
5
|
/** Config accepted by PublisherManager. */
|
|
@@ -8,23 +9,34 @@ type PublisherManagerConfig = {
|
|
|
8
9
|
publisherFundingAmount?: bigint;
|
|
9
10
|
};
|
|
10
11
|
export declare class PublisherManager<UtilsType extends L1TxUtils = L1TxUtils> {
|
|
11
|
-
|
|
12
|
+
protected publishers: UtilsType[];
|
|
12
13
|
private log;
|
|
13
14
|
private config;
|
|
14
15
|
private static readonly FUNDING_CHECK_INTERVAL_MS;
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
protected funder?: UtilsType;
|
|
17
|
+
protected readonly fundingPromise?: RunningPromise;
|
|
18
|
+
private started;
|
|
17
19
|
constructor(publishers: UtilsType[], config: PublisherManagerConfig, opts?: {
|
|
18
20
|
bindings?: LoggerBindings;
|
|
19
21
|
funder?: UtilsType;
|
|
20
22
|
});
|
|
21
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Clears any interrupted flag left by a previous {@link stop} so publishing works again after a restart,
|
|
25
|
+
* loads the state of all publishers and the funder, and starts periodic funding checks. Idempotent: a
|
|
26
|
+
* start while already started is a no-op, so it never re-runs `loadStateAndResumeMonitoring` (which
|
|
27
|
+
* would spawn a duplicate background monitor per pending nonce). Lifecycle calls are expected to be
|
|
28
|
+
* serialized by the caller.
|
|
29
|
+
*/
|
|
22
30
|
start(): Promise<void>;
|
|
23
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* Stops the funding loop, interrupts all publishers so no further L1 txs are sent, and waits (bounded)
|
|
33
|
+
* for their in-flight tx monitor loops to wind down. Idempotent, and the manager may be restarted
|
|
34
|
+
* afterwards via {@link start}, which clears the interrupted flag.
|
|
35
|
+
*/
|
|
24
36
|
stop(): Promise<void>;
|
|
25
37
|
getAvailablePublisher(filter?: PublisherFilter<UtilsType>): Promise<UtilsType>;
|
|
26
38
|
private triggerFundingIfNeeded;
|
|
27
39
|
private fundPublishers;
|
|
28
40
|
}
|
|
29
41
|
export {};
|
|
30
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
42
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGlzaGVyX21hbmFnZXIuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9wdWJsaXNoZXJfbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQWUsS0FBSyxjQUFjLEVBQWdCLE1BQU0sdUJBQXVCLENBQUM7QUFDdkYsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBR25FLE9BQU8sRUFBRSxTQUFTLEVBQWdCLE1BQU0sd0JBQXdCLENBQUM7QUF3QmpFLE1BQU0sTUFBTSxlQUFlLENBQUMsU0FBUyxTQUFTLFNBQVMsSUFBSSxDQUFDLEtBQUssRUFBRSxTQUFTLEtBQUssT0FBTyxDQUFDO0FBRXpGLDJDQUEyQztBQUMzQyxLQUFLLHNCQUFzQixHQUFHO0lBQzVCLDJCQUEyQixDQUFDLEVBQUUsT0FBTyxDQUFDO0lBQ3RDLHlCQUF5QixDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ25DLHNCQUFzQixDQUFDLEVBQUUsTUFBTSxDQUFDO0NBQ2pDLENBQUM7QUFFRixxQkFBYSxnQkFBZ0IsQ0FBQyxTQUFTLFNBQVMsU0FBUyxHQUFHLFNBQVM7SUFTakUsU0FBUyxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUU7SUFSbkMsT0FBTyxDQUFDLEdBQUcsQ0FBUztJQUNwQixPQUFPLENBQUMsTUFBTSxDQUF5QjtJQUN2QyxPQUFPLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyx5QkFBeUIsQ0FBaUI7SUFDbEUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFLFNBQVMsQ0FBQztJQUM3QixTQUFTLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxFQUFFLGNBQWMsQ0FBQztJQUNuRCxPQUFPLENBQUMsT0FBTyxDQUFTO0lBRXhCLFlBQ1ksVUFBVSxFQUFFLFNBQVMsRUFBRSxFQUNqQyxNQUFNLEVBQUUsc0JBQXNCLEVBQzlCLElBQUksQ0FBQyxFQUFFO1FBQUUsUUFBUSxDQUFDLEVBQUUsY0FBYyxDQUFDO1FBQUMsTUFBTSxDQUFDLEVBQUUsU0FBUyxDQUFBO0tBQUUsRUE2QnpEO0lBRUQ7Ozs7OztPQU1HO0lBQ1UsS0FBSyxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FtQmxDO0lBRUQ7Ozs7T0FJRztJQUNVLElBQUksSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBV2pDO0lBUVkscUJBQXFCLENBQUMsTUFBTSxHQUFFLGVBQWUsQ0FBQyxTQUFTLENBQWMsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBd0R0RztZQUdhLHNCQUFzQjtZQXFDdEIsY0FBYztDQVU3QiJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publisher_manager.d.ts","sourceRoot":"","sources":["../src/publisher_manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,cAAc,EAAgB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"publisher_manager.d.ts","sourceRoot":"","sources":["../src/publisher_manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,cAAc,EAAgB,MAAM,uBAAuB,CAAC;AACvF,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAGnE,OAAO,EAAE,SAAS,EAAgB,MAAM,wBAAwB,CAAC;AAwBjE,MAAM,MAAM,eAAe,CAAC,SAAS,SAAS,SAAS,IAAI,CAAC,KAAK,EAAE,SAAS,KAAK,OAAO,CAAC;AAEzF,2CAA2C;AAC3C,KAAK,sBAAsB,GAAG;IAC5B,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC,CAAC;AAEF,qBAAa,gBAAgB,CAAC,SAAS,SAAS,SAAS,GAAG,SAAS;IASjE,SAAS,CAAC,UAAU,EAAE,SAAS,EAAE;IARnC,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAAiB;IAClE,SAAS,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC7B,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IACnD,OAAO,CAAC,OAAO,CAAS;IAExB,YACY,UAAU,EAAE,SAAS,EAAE,EACjC,MAAM,EAAE,sBAAsB,EAC9B,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,cAAc,CAAC;QAAC,MAAM,CAAC,EAAE,SAAS,CAAA;KAAE,EA6BzD;IAED;;;;;;OAMG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAmBlC;IAED;;;;OAIG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAWjC;IAQY,qBAAqB,CAAC,MAAM,GAAE,eAAe,CAAC,SAAS,CAAc,GAAG,OAAO,CAAC,SAAS,CAAC,CAwDtG;YAGa,sBAAsB;YAqCtB,cAAc;CAU7B"}
|
|
@@ -30,8 +30,10 @@ export class PublisherManager {
|
|
|
30
30
|
static FUNDING_CHECK_INTERVAL_MS = 2 * 60 * 1000;
|
|
31
31
|
funder;
|
|
32
32
|
fundingPromise;
|
|
33
|
+
started;
|
|
33
34
|
constructor(publishers, config, opts){
|
|
34
35
|
this.publishers = publishers;
|
|
36
|
+
this.started = false;
|
|
35
37
|
this.funder = opts?.funder;
|
|
36
38
|
this.log = createLogger('publisher:manager', opts?.bindings);
|
|
37
39
|
this.log.info(`PublisherManager initialized with ${publishers.length} publishers.`);
|
|
@@ -49,21 +51,48 @@ export class PublisherManager {
|
|
|
49
51
|
this.funder = undefined;
|
|
50
52
|
}
|
|
51
53
|
}
|
|
54
|
+
if (this.funder && hasThreshold && hasAmount) {
|
|
55
|
+
this.fundingPromise = new RunningPromise(()=>this.triggerFundingIfNeeded(), this.log, PublisherManager.FUNDING_CHECK_INTERVAL_MS);
|
|
56
|
+
}
|
|
52
57
|
}
|
|
53
|
-
/**
|
|
58
|
+
/**
|
|
59
|
+
* Clears any interrupted flag left by a previous {@link stop} so publishing works again after a restart,
|
|
60
|
+
* loads the state of all publishers and the funder, and starts periodic funding checks. Idempotent: a
|
|
61
|
+
* start while already started is a no-op, so it never re-runs `loadStateAndResumeMonitoring` (which
|
|
62
|
+
* would spawn a duplicate background monitor per pending nonce). Lifecycle calls are expected to be
|
|
63
|
+
* serialized by the caller.
|
|
64
|
+
*/ async start() {
|
|
65
|
+
if (this.started) {
|
|
66
|
+
this.log.debug('PublisherManager already started, ignoring start');
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
// Clear the interrupted flag set by a previous stop() so a restarted manager can publish again.
|
|
70
|
+
// On a first start this is a no-op (the flag is already clear).
|
|
71
|
+
this.publishers.forEach((pub)=>pub.restart());
|
|
72
|
+
this.funder?.restart();
|
|
54
73
|
await Promise.all([
|
|
55
74
|
...this.publishers.map((pub)=>pub.loadStateAndResumeMonitoring()),
|
|
56
75
|
this.funder?.loadStateAndResumeMonitoring()
|
|
57
76
|
]);
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
77
|
+
this.fundingPromise?.start();
|
|
78
|
+
// Marked started only once fully up, so a start that failed to load state can be retried.
|
|
79
|
+
this.started = true;
|
|
62
80
|
}
|
|
63
|
-
/**
|
|
81
|
+
/**
|
|
82
|
+
* Stops the funding loop, interrupts all publishers so no further L1 txs are sent, and waits (bounded)
|
|
83
|
+
* for their in-flight tx monitor loops to wind down. Idempotent, and the manager may be restarted
|
|
84
|
+
* afterwards via {@link start}, which clears the interrupted flag.
|
|
85
|
+
*/ async stop() {
|
|
86
|
+
this.started = false;
|
|
64
87
|
await this.fundingPromise?.stop();
|
|
65
88
|
this.publishers.forEach((pub)=>pub.interrupt());
|
|
66
89
|
this.funder?.interrupt();
|
|
90
|
+
// Wait for in-flight tx monitor loops to observe the interrupt, so no L1 requests are still
|
|
91
|
+
// being issued after shutdown (e.g. against an anvil instance a test is about to tear down).
|
|
92
|
+
await Promise.all([
|
|
93
|
+
...this.publishers.map((pub)=>pub.waitMonitoringStopped()),
|
|
94
|
+
this.funder?.waitMonitoringStopped()
|
|
95
|
+
]);
|
|
67
96
|
}
|
|
68
97
|
// Finds and prioritises available publishers based on
|
|
69
98
|
// 1. Validity as per the provided filter function
|
|
@@ -97,8 +126,16 @@ export class PublisherManager {
|
|
|
97
126
|
publisher: pub
|
|
98
127
|
};
|
|
99
128
|
}));
|
|
129
|
+
// Discount unfunded publishers: a publisher with no ETH cannot send a tx, so it must never win
|
|
130
|
+
// selection regardless of how favourable its state or last-used time is. Fall back to the full
|
|
131
|
+
// set only if every candidate is unfunded, so behaviour is no worse than before.
|
|
132
|
+
let fundedPublishers = publishersWithBalance.filter((p)=>p.balance > 0n);
|
|
133
|
+
if (fundedPublishers.length === 0) {
|
|
134
|
+
this.log.warn(`All candidate publishers have zero balance; selecting from unfunded publishers.`);
|
|
135
|
+
fundedPublishers = publishersWithBalance;
|
|
136
|
+
}
|
|
100
137
|
// Sort based on state, then balance, then time since last use
|
|
101
|
-
const sortedPublishers =
|
|
138
|
+
const sortedPublishers = fundedPublishers.sort((a, b)=>{
|
|
102
139
|
const stateComparison = sortOrder.indexOf(a.publisher.state) - sortOrder.indexOf(b.publisher.state);
|
|
103
140
|
if (stateComparison !== 0) {
|
|
104
141
|
return stateComparison;
|
package/dest/queries.d.ts
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
|
+
import { type Block } from 'viem';
|
|
2
3
|
import { type L1ContractsConfig } from './config.js';
|
|
3
|
-
import type { ViemPublicClient } from './types.js';
|
|
4
|
+
import type { ViemClient, ViemPublicClient } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Returns the L1 finalized block, or `undefined` if the chain does not yet have one
|
|
7
|
+
* (common on freshly started devnets). Rethrows any other RPC error.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getFinalizedL1Block(client: ViemClient): Promise<Block<bigint, false, 'finalized'> | undefined>;
|
|
10
|
+
/**
|
|
11
|
+
* Returns true if the error originates from an RPC call that failed because
|
|
12
|
+
* the "finalized" (or "safe") block tag is not yet available on the chain.
|
|
13
|
+
*/
|
|
14
|
+
export declare function isFinalizedBlockTagNotFoundError(err: unknown): boolean;
|
|
4
15
|
/** Reads the L1ContractsConfig from L1 contracts. */
|
|
5
16
|
export declare function getL1ContractsConfig(publicClient: ViemPublicClient, addresses: {
|
|
6
17
|
governanceAddress: EthAddress;
|
|
@@ -11,4 +22,4 @@ export declare function getL1ContractsConfig(publicClient: ViemPublicClient, add
|
|
|
11
22
|
rollupVersion: number;
|
|
12
23
|
genesisArchiveTreeRoot: `0x${string}`;
|
|
13
24
|
}>;
|
|
14
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
25
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcmllcy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3F1ZXJpZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTNELE9BQU8sRUFBYSxLQUFLLEtBQUssRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUU3QyxPQUFPLEVBQTRCLEtBQUssaUJBQWlCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFLL0UsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRS9EOzs7R0FHRztBQUNILHdCQUFzQixtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsVUFBVSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxXQUFXLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FTcEg7QUFtQkQ7OztHQUdHO0FBQ0gsd0JBQWdCLGdDQUFnQyxDQUFDLEdBQUcsRUFBRSxPQUFPLEdBQUcsT0FBTyxDQWtCdEU7QUFVRCxxREFBcUQ7QUFDckQsd0JBQXNCLG9CQUFvQixDQUN4QyxZQUFZLEVBQUUsZ0JBQWdCLEVBQzlCLFNBQVMsRUFBRTtJQUFFLGlCQUFpQixFQUFFLFVBQVUsQ0FBQztJQUFDLGFBQWEsQ0FBQyxFQUFFLFVBQVUsQ0FBQTtDQUFFLEdBQ3ZFLE9BQU8sQ0FDUixJQUFJLENBQUMsaUJBQWlCLEVBQUUsc0JBQXNCLENBQUMsR0FBRztJQUNoRCxZQUFZLEVBQUUsTUFBTSxDQUFDO0lBQ3JCLGFBQWEsRUFBRSxNQUFNLENBQUM7SUFDdEIsYUFBYSxFQUFFLE1BQU0sQ0FBQztJQUN0QixzQkFBc0IsRUFBRSxLQUFLLE1BQU0sRUFBRSxDQUFDO0NBQ3ZDLENBQ0YsQ0E2R0EifQ==
|
package/dest/queries.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../src/queries.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAA4B,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAK/E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../src/queries.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAAa,KAAK,KAAK,EAAE,MAAM,MAAM,CAAC;AAE7C,OAAO,EAA4B,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAK/E,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE/D;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,SAAS,CAAC,CASpH;AAmBD;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAkBtE;AAUD,qDAAqD;AACrD,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,gBAAgB,EAC9B,SAAS,EAAE;IAAE,iBAAiB,EAAE,UAAU,CAAC;IAAC,aAAa,CAAC,EAAE,UAAU,CAAA;CAAE,GACvE,OAAO,CACR,IAAI,CAAC,iBAAiB,EAAE,sBAAsB,CAAC,GAAG;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,sBAAsB,EAAE,KAAK,MAAM,EAAE,CAAC;CACvC,CACF,CA6GA"}
|