@aztec/ethereum 0.0.1-commit.b6e433891 → 0.0.1-commit.b8a057fa
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 +12 -7
- 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 +130 -13
- package/dest/contracts/multicall.d.ts.map +1 -1
- package/dest/contracts/multicall.js +203 -94
- 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 +5401 -26
- package/dest/contracts/rollup.d.ts.map +1 -1
- package/dest/contracts/rollup.js +343 -69
- 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 +17 -13
- 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 +9 -1
- package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -1
- package/dest/l1_tx_utils/l1_tx_utils.js +138 -57
- 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 +34 -8
- package/dest/publisher_manager.d.ts.map +1 -1
- package/dest/publisher_manager.js +119 -8
- 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 +37 -6
- package/dest/test/eth_cheat_codes.d.ts.map +1 -1
- package/dest/test/eth_cheat_codes.js +89 -41
- 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 +8 -1
- package/dest/test/start_anvil.d.ts.map +1 -1
- package/dest/test/start_anvil.js +16 -2
- 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 +13 -5
- package/src/contracts/index.ts +2 -2
- package/src/contracts/multicall.ts +247 -106
- package/src/contracts/outbox.ts +42 -8
- package/src/contracts/rollup.ts +382 -69
- package/src/contracts/{tally_slashing_proposer.ts → slashing_proposer.ts} +14 -16
- package/src/deploy_aztec_l1_contracts.ts +16 -14
- 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 +122 -48
- 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 +143 -12
- 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 +82 -45
- package/src/test/index.ts +1 -0
- package/src/test/rollup_cheat_codes.ts +115 -6
- package/src/test/start_anvil.ts +25 -2
- 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
|
@@ -7,7 +7,7 @@ import { EthAddress } from '@aztec/foundation/eth-address';
|
|
|
7
7
|
import { Signature } from '@aztec/foundation/eth-signature';
|
|
8
8
|
import { hexToBuffer } from '@aztec/foundation/string';
|
|
9
9
|
import { SlasherAbi } from '@aztec/l1-artifacts/SlasherAbi';
|
|
10
|
-
import {
|
|
10
|
+
import { SlashingProposerAbi } from '@aztec/l1-artifacts/SlashingProposerAbi';
|
|
11
11
|
|
|
12
12
|
import {
|
|
13
13
|
type GetContractReturnType,
|
|
@@ -19,13 +19,11 @@ import {
|
|
|
19
19
|
} from 'viem';
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* Wrapper around the
|
|
22
|
+
* Wrapper around the SlashingProposer contract that provides
|
|
23
23
|
* a TypeScript interface for interacting with the consensus-based slashing system.
|
|
24
24
|
*/
|
|
25
|
-
export class
|
|
26
|
-
private readonly contract: GetContractReturnType<typeof
|
|
27
|
-
|
|
28
|
-
public readonly type = 'tally' as const;
|
|
25
|
+
export class SlashingProposerContract {
|
|
26
|
+
private readonly contract: GetContractReturnType<typeof SlashingProposerAbi, ViemClient>;
|
|
29
27
|
|
|
30
28
|
constructor(
|
|
31
29
|
public readonly client: ViemClient,
|
|
@@ -33,7 +31,7 @@ export class TallySlashingProposerContract {
|
|
|
33
31
|
) {
|
|
34
32
|
this.contract = getContract({
|
|
35
33
|
address: typeof address === 'string' ? address : address.toString(),
|
|
36
|
-
abi:
|
|
34
|
+
abi: SlashingProposerAbi,
|
|
37
35
|
client,
|
|
38
36
|
});
|
|
39
37
|
}
|
|
@@ -136,12 +134,12 @@ export class TallySlashingProposerContract {
|
|
|
136
134
|
|
|
137
135
|
/** Tries to extract a VoteCast event from the given logs. */
|
|
138
136
|
public tryExtractVoteCastEvent(logs: Log[]) {
|
|
139
|
-
return tryExtractEvent(logs, this.address.toString(),
|
|
137
|
+
return tryExtractEvent(logs, this.address.toString(), SlashingProposerAbi, 'VoteCast');
|
|
140
138
|
}
|
|
141
139
|
|
|
142
140
|
/** Tries to extract a RoundExecuted event from the given logs. */
|
|
143
141
|
public tryExtractRoundExecutedEvent(logs: Log[]) {
|
|
144
|
-
return tryExtractEvent(logs, this.address.toString(),
|
|
142
|
+
return tryExtractEvent(logs, this.address.toString(), SlashingProposerAbi, 'RoundExecuted');
|
|
145
143
|
}
|
|
146
144
|
|
|
147
145
|
/**
|
|
@@ -161,9 +159,9 @@ export class TallySlashingProposerContract {
|
|
|
161
159
|
|
|
162
160
|
return {
|
|
163
161
|
to: this.contract.address,
|
|
164
|
-
abi:
|
|
162
|
+
abi: SlashingProposerAbi,
|
|
165
163
|
data: encodeFunctionData({
|
|
166
|
-
abi:
|
|
164
|
+
abi: SlashingProposerAbi,
|
|
167
165
|
functionName: 'vote',
|
|
168
166
|
args: [votes, signature.toViemSignature()],
|
|
169
167
|
}),
|
|
@@ -173,7 +171,7 @@ export class TallySlashingProposerContract {
|
|
|
173
171
|
/** Returns the typed data definition to EIP712-sign for voting */
|
|
174
172
|
public buildVoteTypedData(votes: Hex, slot: SlotNumber): TypedDataDefinition {
|
|
175
173
|
const domain = {
|
|
176
|
-
name: '
|
|
174
|
+
name: 'SlashingProposer',
|
|
177
175
|
version: '1',
|
|
178
176
|
chainId: this.client.chain.id,
|
|
179
177
|
verifyingContract: this.contract.address,
|
|
@@ -209,9 +207,9 @@ export class TallySlashingProposerContract {
|
|
|
209
207
|
public buildVoteRequestWithSignature(votes: Hex, signature: { v: number; r: Hex; s: Hex }): L1TxRequest {
|
|
210
208
|
return {
|
|
211
209
|
to: this.contract.address,
|
|
212
|
-
abi:
|
|
210
|
+
abi: SlashingProposerAbi,
|
|
213
211
|
data: encodeFunctionData({
|
|
214
|
-
abi:
|
|
212
|
+
abi: SlashingProposerAbi,
|
|
215
213
|
functionName: 'vote',
|
|
216
214
|
args: [votes, signature],
|
|
217
215
|
}),
|
|
@@ -227,9 +225,9 @@ export class TallySlashingProposerContract {
|
|
|
227
225
|
public buildExecuteRoundRequest(round: bigint, committees: EthAddress[][]): L1TxRequest {
|
|
228
226
|
return {
|
|
229
227
|
to: this.contract.address,
|
|
230
|
-
abi: mergeAbis([
|
|
228
|
+
abi: mergeAbis([SlashingProposerAbi, SlasherAbi]),
|
|
231
229
|
data: encodeFunctionData({
|
|
232
|
-
abi:
|
|
230
|
+
abi: SlashingProposerAbi,
|
|
233
231
|
functionName: 'executeRound',
|
|
234
232
|
args: [round, committees.map(c => c.map(addr => addr.toString()))],
|
|
235
233
|
}),
|
|
@@ -5,12 +5,12 @@ import { jsonStringify } from '@aztec/foundation/json-rpc';
|
|
|
5
5
|
import { createLogger } from '@aztec/foundation/log';
|
|
6
6
|
import { promiseWithResolvers } from '@aztec/foundation/promise';
|
|
7
7
|
import type { Fr } from '@aztec/foundation/schemas';
|
|
8
|
-
import { fileURLToPath } from '@aztec/foundation/url';
|
|
9
8
|
|
|
10
9
|
import { bn254 } from '@noble/curves/bn254';
|
|
11
10
|
import type { Abi, Narrow } from 'abitype';
|
|
12
11
|
import { spawn } from 'child_process';
|
|
13
12
|
import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'fs';
|
|
13
|
+
import { createRequire } from 'node:module';
|
|
14
14
|
import { tmpdir } from 'os';
|
|
15
15
|
import { dirname, join, resolve } from 'path';
|
|
16
16
|
import readline from 'readline';
|
|
@@ -19,7 +19,7 @@ import { mainnet, sepolia } from 'viem/chains';
|
|
|
19
19
|
|
|
20
20
|
import { createEthereumChain, isAnvilTestChain } from './chain.js';
|
|
21
21
|
import { createExtendedL1Client } from './client.js';
|
|
22
|
-
import type
|
|
22
|
+
import { type L1ContractsConfig, assertValidSlotDurations } from './config.js';
|
|
23
23
|
import { deployMulticall3 } from './contracts/multicall.js';
|
|
24
24
|
import { RollupContract } from './contracts/rollup.js';
|
|
25
25
|
import type { L1ContractAddresses } from './l1_contract_addresses.js';
|
|
@@ -27,6 +27,8 @@ import type { ExtendedViemWalletClient } from './types.js';
|
|
|
27
27
|
|
|
28
28
|
const logger = createLogger('ethereum:deploy_aztec_l1_contracts');
|
|
29
29
|
|
|
30
|
+
const require = createRequire(import.meta.url);
|
|
31
|
+
|
|
30
32
|
const JSON_DEPLOY_RESULT_PREFIX = 'JSON DEPLOY RESULT:';
|
|
31
33
|
|
|
32
34
|
/**
|
|
@@ -123,15 +125,13 @@ export interface ValidatorJson {
|
|
|
123
125
|
}
|
|
124
126
|
|
|
125
127
|
/**
|
|
126
|
-
* Gets the path to the l1-contracts foundry artifacts directory.
|
|
127
|
-
*
|
|
128
|
-
*
|
|
128
|
+
* Gets the path to the l1-contracts foundry artifacts directory bundled inside @aztec/l1-artifacts.
|
|
129
|
+
* Resolved through the package (its "." export -> dest/index.js) so it works whether the package is
|
|
130
|
+
* linked via portal (monorepo) or installed under node_modules (published npm) — resolution follows
|
|
131
|
+
* the symlink in the portal case. The bundled foundry subtree sits alongside dest/, at <pkg>/l1-contracts.
|
|
129
132
|
*/
|
|
130
133
|
export function getL1ContractsPath(): string {
|
|
131
|
-
|
|
132
|
-
// Go up from yarn-project/ethereum/dest to yarn-project, then to l1-artifacts/l1-contracts
|
|
133
|
-
const l1ContractsPath = resolve(currentDir, '..', '..', 'l1-artifacts', 'l1-contracts');
|
|
134
|
-
return l1ContractsPath;
|
|
134
|
+
return resolve(dirname(require.resolve('@aztec/l1-artifacts')), '..', 'l1-contracts');
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
// Cached deployment directory
|
|
@@ -230,7 +230,6 @@ export function computeValidatorData(operator: Operator): ValidatorJson {
|
|
|
230
230
|
export interface RollupUpgradeAddresses {
|
|
231
231
|
rollupAddress: string;
|
|
232
232
|
verifierAddress: string;
|
|
233
|
-
slashFactoryAddress: string;
|
|
234
233
|
inboxAddress: string;
|
|
235
234
|
outboxAddress: string;
|
|
236
235
|
feeJuicePortalAddress: string;
|
|
@@ -243,7 +242,6 @@ export interface RollupUpgradeAddresses {
|
|
|
243
242
|
export interface ForgeRollupUpgradeResult {
|
|
244
243
|
rollupAddress: Hex;
|
|
245
244
|
verifierAddress: Hex;
|
|
246
|
-
slashFactoryAddress: Hex;
|
|
247
245
|
inboxAddress: Hex;
|
|
248
246
|
outboxAddress: Hex;
|
|
249
247
|
feeJuicePortalAddress: Hex;
|
|
@@ -284,6 +282,7 @@ export async function deployAztecL1Contracts(
|
|
|
284
282
|
args: DeployAztecL1ContractsArgs,
|
|
285
283
|
): Promise<DeployAztecL1ContractsReturnType> {
|
|
286
284
|
logger.info(`Deploying L1 contracts with config: ${jsonStringify(args)}`);
|
|
285
|
+
assertValidSlotDurations(args);
|
|
287
286
|
if (args.initialValidators && args.initialValidators.length > 0 && args.existingTokenAddress) {
|
|
288
287
|
throw new Error(
|
|
289
288
|
'Cannot deploy with both initialValidators and existingTokenAddress. ' +
|
|
@@ -403,7 +402,6 @@ export async function deployAztecL1Contracts(
|
|
|
403
402
|
governanceProposerAddress: EthAddress.fromString(result.governanceProposerAddress),
|
|
404
403
|
governanceAddress: EthAddress.fromString(result.governanceAddress),
|
|
405
404
|
stakingAssetAddress: EthAddress.fromString(result.stakingAssetAddress),
|
|
406
|
-
slashFactoryAddress: result.slashFactoryAddress ? EthAddress.fromString(result.slashFactoryAddress) : undefined,
|
|
407
405
|
feeAssetHandlerAddress: result.feeAssetHandlerAddress
|
|
408
406
|
? EthAddress.fromString(result.feeAssetHandlerAddress)
|
|
409
407
|
: undefined,
|
|
@@ -585,13 +583,18 @@ export function getDeployRollupForUpgradeEnvVars(
|
|
|
585
583
|
AZTEC_EXIT_DELAY_SECONDS: args.exitDelaySeconds.toString(),
|
|
586
584
|
AZTEC_PROVING_COST_PER_MANA: args.provingCostPerMana.toString(),
|
|
587
585
|
AZTEC_INITIAL_ETH_PER_FEE_ASSET: args.initialEthPerFeeAsset.toString(),
|
|
588
|
-
|
|
586
|
+
AZTEC_SLASHER_ENABLED: args.slasherEnabled ? 'true' : 'false',
|
|
589
587
|
AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS: args.slashingRoundSizeInEpochs.toString(),
|
|
590
588
|
AZTEC_SLASHING_QUORUM: args.slashingQuorum?.toString(),
|
|
591
589
|
AZTEC_SLASHING_OFFSET_IN_ROUNDS: args.slashingOffsetInRounds.toString(),
|
|
592
590
|
AZTEC_SLASH_AMOUNT_SMALL: args.slashAmountSmall.toString(),
|
|
593
591
|
AZTEC_SLASH_AMOUNT_MEDIUM: args.slashAmountMedium.toString(),
|
|
594
592
|
AZTEC_SLASH_AMOUNT_LARGE: args.slashAmountLarge.toString(),
|
|
593
|
+
AZTEC_ENTRY_QUEUE_BOOTSTRAP_VALIDATOR_SET_SIZE: args.entryQueueBootstrapValidatorSetSize.toString(),
|
|
594
|
+
AZTEC_ENTRY_QUEUE_BOOTSTRAP_FLUSH_SIZE: args.entryQueueBootstrapFlushSize.toString(),
|
|
595
|
+
AZTEC_ENTRY_QUEUE_FLUSH_SIZE_MIN: args.entryQueueFlushSizeMin.toString(),
|
|
596
|
+
AZTEC_ENTRY_QUEUE_FLUSH_SIZE_QUOTIENT: args.entryQueueFlushSizeQuotient.toString(),
|
|
597
|
+
AZTEC_ENTRY_QUEUE_MAX_FLUSH_SIZE: args.entryQueueMaxFlushSize.toString(),
|
|
595
598
|
} as const;
|
|
596
599
|
}
|
|
597
600
|
|
|
@@ -645,6 +648,5 @@ export const deployRollupForUpgrade = async (
|
|
|
645
648
|
|
|
646
649
|
return {
|
|
647
650
|
rollup,
|
|
648
|
-
slashFactoryAddress: result.slashFactoryAddress,
|
|
649
651
|
};
|
|
650
652
|
};
|
package/src/l1_artifacts.ts
CHANGED
|
@@ -3,10 +3,6 @@ import {
|
|
|
3
3
|
CoinIssuerBytecode,
|
|
4
4
|
DateGatedRelayerAbi,
|
|
5
5
|
DateGatedRelayerBytecode,
|
|
6
|
-
EmpireSlasherDeploymentExtLibAbi,
|
|
7
|
-
EmpireSlasherDeploymentExtLibBytecode,
|
|
8
|
-
EmpireSlashingProposerAbi,
|
|
9
|
-
EmpireSlashingProposerBytecode,
|
|
10
6
|
FeeAssetHandlerAbi,
|
|
11
7
|
FeeAssetHandlerBytecode,
|
|
12
8
|
FeeJuicePortalAbi,
|
|
@@ -42,16 +38,14 @@ import {
|
|
|
42
38
|
RollupLinkReferences,
|
|
43
39
|
RollupOperationsExtLibAbi,
|
|
44
40
|
RollupOperationsExtLibBytecode,
|
|
45
|
-
SlashFactoryAbi,
|
|
46
|
-
SlashFactoryBytecode,
|
|
47
41
|
SlasherAbi,
|
|
48
42
|
SlasherBytecode,
|
|
43
|
+
SlasherDeploymentExtLibAbi,
|
|
44
|
+
SlasherDeploymentExtLibBytecode,
|
|
45
|
+
SlashingProposerAbi,
|
|
46
|
+
SlashingProposerBytecode,
|
|
49
47
|
StakingAssetHandlerAbi,
|
|
50
48
|
StakingAssetHandlerBytecode,
|
|
51
|
-
TallySlasherDeploymentExtLibAbi,
|
|
52
|
-
TallySlasherDeploymentExtLibBytecode,
|
|
53
|
-
TallySlashingProposerAbi,
|
|
54
|
-
TallySlashingProposerBytecode,
|
|
55
49
|
TestERC20Abi,
|
|
56
50
|
TestERC20Bytecode,
|
|
57
51
|
ValidatorOperationsExtLibAbi,
|
|
@@ -107,15 +101,10 @@ export const RollupArtifact = {
|
|
|
107
101
|
contractAbi: RewardExtLibAbi,
|
|
108
102
|
contractBytecode: RewardExtLibBytecode as Hex,
|
|
109
103
|
},
|
|
110
|
-
|
|
111
|
-
name: '
|
|
112
|
-
contractAbi:
|
|
113
|
-
contractBytecode:
|
|
114
|
-
},
|
|
115
|
-
EmpireSlasherDeploymentExtLib: {
|
|
116
|
-
name: 'EmpireSlasherDeploymentExtLib',
|
|
117
|
-
contractAbi: EmpireSlasherDeploymentExtLibAbi,
|
|
118
|
-
contractBytecode: EmpireSlasherDeploymentExtLibBytecode as Hex,
|
|
104
|
+
SlasherDeploymentExtLib: {
|
|
105
|
+
name: 'SlasherDeploymentExtLib',
|
|
106
|
+
contractAbi: SlasherDeploymentExtLibAbi,
|
|
107
|
+
contractBytecode: SlasherDeploymentExtLibBytecode as Hex,
|
|
119
108
|
},
|
|
120
109
|
},
|
|
121
110
|
},
|
|
@@ -175,22 +164,10 @@ export const SlasherArtifact = {
|
|
|
175
164
|
contractBytecode: SlasherBytecode as Hex,
|
|
176
165
|
};
|
|
177
166
|
|
|
178
|
-
export const
|
|
179
|
-
name: '
|
|
180
|
-
contractAbi:
|
|
181
|
-
contractBytecode:
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
export const TallySlashingProposerArtifact = {
|
|
185
|
-
name: 'TallySlashingProposer',
|
|
186
|
-
contractAbi: TallySlashingProposerAbi,
|
|
187
|
-
contractBytecode: TallySlashingProposerBytecode as Hex,
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
export const SlashFactoryArtifact = {
|
|
191
|
-
name: 'SlashFactory',
|
|
192
|
-
contractAbi: SlashFactoryAbi,
|
|
193
|
-
contractBytecode: SlashFactoryBytecode as Hex,
|
|
167
|
+
export const SlashingProposerArtifact = {
|
|
168
|
+
name: 'SlashingProposer',
|
|
169
|
+
contractAbi: SlashingProposerAbi,
|
|
170
|
+
contractBytecode: SlashingProposerBytecode as Hex,
|
|
194
171
|
};
|
|
195
172
|
|
|
196
173
|
export const RegisterNewRollupVersionPayloadArtifact = {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import type { ConfigMappingsType } from '@aztec/foundation/config';
|
|
1
|
+
import type { ConfigMapping, ConfigMappingsType } from '@aztec/foundation/config';
|
|
2
2
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
|
-
import { schemas
|
|
3
|
+
import { schemas } from '@aztec/foundation/schemas';
|
|
4
4
|
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Required L1 contract address keys.
|
|
9
9
|
* NOTE: When changing this list, make sure to update CLI & CI scripts accordingly.
|
|
10
10
|
* For reference: https://github.com/AztecProtocol/aztec-packages/pull/5553
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
const REQUIRED_L1_CONTRACT_ADDRESS_KEYS = [
|
|
13
13
|
'rollupAddress',
|
|
14
14
|
'registryAddress',
|
|
15
15
|
'inboxAddress',
|
|
@@ -23,102 +23,128 @@ export const L1ContractsNames = [
|
|
|
23
23
|
'stakingAssetAddress',
|
|
24
24
|
] as const;
|
|
25
25
|
|
|
26
|
+
/** Optional L1 contract address keys — present only in some deployments. */
|
|
27
|
+
export const OPTIONAL_L1_CONTRACT_ADDRESS_KEYS = [
|
|
28
|
+
'feeAssetHandlerAddress',
|
|
29
|
+
'stakingAssetHandlerAddress',
|
|
30
|
+
'zkPassportVerifierAddress',
|
|
31
|
+
'gseAddress',
|
|
32
|
+
'dateGatedRelayerAddress',
|
|
33
|
+
] as const;
|
|
34
|
+
|
|
35
|
+
type RequiredContractKey = (typeof REQUIRED_L1_CONTRACT_ADDRESS_KEYS)[number];
|
|
36
|
+
type OptionalContractKey = (typeof OPTIONAL_L1_CONTRACT_ADDRESS_KEYS)[number];
|
|
37
|
+
|
|
26
38
|
/** Provides the directory of current L1 contract addresses */
|
|
27
39
|
export type L1ContractAddresses = {
|
|
28
|
-
[K in
|
|
40
|
+
[K in RequiredContractKey]: EthAddress;
|
|
29
41
|
} & {
|
|
30
|
-
|
|
31
|
-
feeAssetHandlerAddress?: EthAddress | undefined;
|
|
32
|
-
stakingAssetHandlerAddress?: EthAddress | undefined;
|
|
33
|
-
zkPassportVerifierAddress?: EthAddress | undefined;
|
|
34
|
-
gseAddress?: EthAddress | undefined;
|
|
35
|
-
dateGatedRelayerAddress?: EthAddress | undefined;
|
|
42
|
+
[K in OptionalContractKey]?: EthAddress;
|
|
36
43
|
};
|
|
37
44
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
feeJuiceAddress: schemas.EthAddress,
|
|
45
|
-
stakingAssetAddress: schemas.EthAddress,
|
|
46
|
-
feeJuicePortalAddress: schemas.EthAddress,
|
|
47
|
-
coinIssuerAddress: schemas.EthAddress,
|
|
48
|
-
rewardDistributorAddress: schemas.EthAddress,
|
|
49
|
-
governanceProposerAddress: schemas.EthAddress,
|
|
50
|
-
governanceAddress: schemas.EthAddress,
|
|
51
|
-
slashFactoryAddress: schemas.EthAddress.optional(),
|
|
52
|
-
feeAssetHandlerAddress: schemas.EthAddress.optional(),
|
|
53
|
-
stakingAssetHandlerAddress: schemas.EthAddress.optional(),
|
|
54
|
-
zkPassportVerifierAddress: schemas.EthAddress.optional(),
|
|
55
|
-
gseAddress: schemas.EthAddress.optional(),
|
|
56
|
-
dateGatedRelayerAddress: schemas.EthAddress.optional(),
|
|
57
|
-
}),
|
|
58
|
-
);
|
|
45
|
+
/**
|
|
46
|
+
* Names of required L1 contract addresses.
|
|
47
|
+
* NOTE: When changing the set of contracts, update CLI & CI scripts accordingly.
|
|
48
|
+
* For reference: https://github.com/AztecProtocol/aztec-packages/pull/5553
|
|
49
|
+
*/
|
|
50
|
+
export const L1ContractsNames = REQUIRED_L1_CONTRACT_ADDRESS_KEYS;
|
|
59
51
|
|
|
60
52
|
const parseEnv = (val: string) => EthAddress.fromString(val);
|
|
53
|
+
const addrEnv = (description: string, env?: ConfigMapping<EthAddress>['env']): ConfigMapping<EthAddress> => ({
|
|
54
|
+
description,
|
|
55
|
+
parseEnv,
|
|
56
|
+
...(env && { env }),
|
|
57
|
+
});
|
|
61
58
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
parseEnv,
|
|
87
|
-
},
|
|
88
|
-
outboxAddress: {
|
|
89
|
-
description: 'The deployed L1 outbox contract address.',
|
|
90
|
-
parseEnv,
|
|
91
|
-
},
|
|
92
|
-
feeJuiceAddress: {
|
|
93
|
-
description: 'The deployed L1 Fee Juice contract address.',
|
|
94
|
-
parseEnv,
|
|
95
|
-
},
|
|
96
|
-
stakingAssetAddress: {
|
|
97
|
-
description: 'The deployed L1 staking asset contract address.',
|
|
98
|
-
parseEnv,
|
|
99
|
-
},
|
|
100
|
-
feeJuicePortalAddress: {
|
|
101
|
-
description: 'The deployed L1 Fee Juice portal contract address.',
|
|
102
|
-
parseEnv,
|
|
103
|
-
},
|
|
104
|
-
coinIssuerAddress: {
|
|
105
|
-
description: 'The deployed L1 coinIssuer contract address',
|
|
106
|
-
parseEnv,
|
|
107
|
-
},
|
|
108
|
-
rewardDistributorAddress: {
|
|
109
|
-
description: 'The deployed L1 rewardDistributor contract address',
|
|
110
|
-
parseEnv,
|
|
111
|
-
},
|
|
112
|
-
governanceProposerAddress: {
|
|
113
|
-
description: 'The deployed L1 governanceProposer contract address',
|
|
114
|
-
parseEnv,
|
|
115
|
-
},
|
|
116
|
-
governanceAddress: {
|
|
117
|
-
description: 'The deployed L1 governance contract address',
|
|
118
|
-
parseEnv,
|
|
119
|
-
},
|
|
120
|
-
stakingAssetHandlerAddress: {
|
|
121
|
-
description: 'The deployed L1 stakingAssetHandler contract address',
|
|
122
|
-
parseEnv,
|
|
123
|
-
},
|
|
59
|
+
/**
|
|
60
|
+
* Config mapping for all L1 contract addresses.
|
|
61
|
+
* This is the single source of truth for which contract addresses exist and how to parse them.
|
|
62
|
+
*/
|
|
63
|
+
export const l1ContractAddressesMapping: ConfigMappingsType<L1ContractAddresses> = {
|
|
64
|
+
rollupAddress: addrEnv('The deployed L1 rollup contract address.'),
|
|
65
|
+
registryAddress: addrEnv('The deployed L1 registry contract address.', 'REGISTRY_CONTRACT_ADDRESS'),
|
|
66
|
+
inboxAddress: addrEnv('The deployed L1 inbox contract address.'),
|
|
67
|
+
outboxAddress: addrEnv('The deployed L1 outbox contract address.'),
|
|
68
|
+
feeJuiceAddress: addrEnv('The deployed L1 Fee Juice contract address.'),
|
|
69
|
+
feeJuicePortalAddress: addrEnv('The deployed L1 Fee Juice portal contract address.'),
|
|
70
|
+
coinIssuerAddress: addrEnv('The deployed L1 coinIssuer contract address'),
|
|
71
|
+
rewardDistributorAddress: addrEnv('The deployed L1 rewardDistributor contract address'),
|
|
72
|
+
governanceProposerAddress: addrEnv('The deployed L1 governanceProposer contract address'),
|
|
73
|
+
governanceAddress: addrEnv('The deployed L1 governance contract address'),
|
|
74
|
+
stakingAssetAddress: addrEnv('The deployed L1 staking asset contract address.'),
|
|
75
|
+
feeAssetHandlerAddress: addrEnv(
|
|
76
|
+
'The deployed L1 feeAssetHandler contract address',
|
|
77
|
+
'FEE_ASSET_HANDLER_CONTRACT_ADDRESS',
|
|
78
|
+
),
|
|
79
|
+
stakingAssetHandlerAddress: addrEnv('The deployed L1 stakingAssetHandler contract address'),
|
|
80
|
+
zkPassportVerifierAddress: addrEnv('The deployed L1 ZK passport verifier contract address'),
|
|
81
|
+
gseAddress: addrEnv('The deployed L1 GSE contract address'),
|
|
82
|
+
dateGatedRelayerAddress: addrEnv('The deployed L1 date-gated relayer contract address'),
|
|
124
83
|
};
|
|
84
|
+
|
|
85
|
+
/** Keys present in {@link l1ContractAddressesMapping}. */
|
|
86
|
+
export type L1ContractAddressMappingKey = keyof typeof l1ContractAddressesMapping;
|
|
87
|
+
|
|
88
|
+
type RequiredAddressShape = { [K in RequiredContractKey]: typeof schemas.EthAddress };
|
|
89
|
+
type OptionalAddressShape = { [K in OptionalContractKey]: ReturnType<typeof schemas.EthAddress.optional> };
|
|
90
|
+
|
|
91
|
+
export const L1ContractAddressesSchema = z.object({
|
|
92
|
+
...(Object.fromEntries(REQUIRED_L1_CONTRACT_ADDRESS_KEYS.map(k => [k, schemas.EthAddress])) as RequiredAddressShape),
|
|
93
|
+
...(Object.fromEntries(
|
|
94
|
+
OPTIONAL_L1_CONTRACT_ADDRESS_KEYS.map(k => [k, schemas.EthAddress.optional()]),
|
|
95
|
+
) as OptionalAddressShape),
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Selects entries from {@link l1ContractAddressesMapping} so composed configs can reuse the same
|
|
100
|
+
* env vars, descriptions, and parsers without duplicating definitions.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* const mappings = {
|
|
105
|
+
* ...pickL1ContractAddressMappings('rollupAddress'),
|
|
106
|
+
* nodeId: { ... },
|
|
107
|
+
* };
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
export function pickL1ContractAddressMappings<const K extends readonly L1ContractAddressMappingKey[]>(
|
|
111
|
+
...keys: K
|
|
112
|
+
): Pick<typeof l1ContractAddressesMapping, K[number]> {
|
|
113
|
+
return Object.fromEntries(keys.map(key => [key, l1ContractAddressesMapping[key]] as const)) as Pick<
|
|
114
|
+
typeof l1ContractAddressesMapping,
|
|
115
|
+
K[number]
|
|
116
|
+
>;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Like {@link pickL1ContractAddressMappings}, but returns a fragment of {@link L1ContractAddressesSchema}'s shape for
|
|
121
|
+
* spreading into `z.object({ ...pickL1ContractAddressesSchemaShape('rollupAddress'), localField: z... })`.
|
|
122
|
+
*/
|
|
123
|
+
export function pickL1ContractAddressesSchema<const K extends readonly L1ContractAddressMappingKey[]>(
|
|
124
|
+
...keys: K
|
|
125
|
+
): Pick<typeof L1ContractAddressesSchema.shape, K[number]> {
|
|
126
|
+
return Object.fromEntries(keys.map(key => [key, L1ContractAddressesSchema.shape[key]])) as Pick<
|
|
127
|
+
typeof L1ContractAddressesSchema.shape,
|
|
128
|
+
K[number]
|
|
129
|
+
>;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Builds an {@link L1ContractAddresses} object from config that stores those fields at the top level. */
|
|
133
|
+
export function pickL1ContractAddresses<T extends L1ContractAddresses>(config: T): L1ContractAddresses {
|
|
134
|
+
const result: Partial<L1ContractAddresses> = {};
|
|
135
|
+
for (const key of REQUIRED_L1_CONTRACT_ADDRESS_KEYS) {
|
|
136
|
+
result[key] = config[key];
|
|
137
|
+
}
|
|
138
|
+
for (const key of OPTIONAL_L1_CONTRACT_ADDRESS_KEYS) {
|
|
139
|
+
const v = config[key];
|
|
140
|
+
if (v !== undefined) {
|
|
141
|
+
result[key] = v;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return result as L1ContractAddresses;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function randomL1ContractAddresses(includeOptional: boolean = false): L1ContractAddresses {
|
|
148
|
+
const keys = includeOptional ? [...L1ContractsNames, ...OPTIONAL_L1_CONTRACT_ADDRESS_KEYS] : L1ContractsNames;
|
|
149
|
+
return Object.fromEntries(keys.map(name => [name, EthAddress.random()])) as L1ContractAddresses;
|
|
150
|
+
}
|
package/src/l1_reader.ts
CHANGED
|
@@ -8,29 +8,23 @@ import {
|
|
|
8
8
|
import { type L1ContractAddresses, l1ContractAddressesMapping } from './l1_contract_addresses.js';
|
|
9
9
|
|
|
10
10
|
/** Configuration of the L1GlobalReader. */
|
|
11
|
-
export
|
|
11
|
+
export type L1ReaderConfig = {
|
|
12
12
|
/** List of URLs of Ethereum RPC nodes that services will connect to (comma separated). */
|
|
13
13
|
l1RpcUrls: string[];
|
|
14
14
|
/** The RPC Url of the ethereum debug host for trace and debug methods. */
|
|
15
15
|
l1DebugRpcUrls: string[];
|
|
16
16
|
/** The chain ID of the ethereum host. */
|
|
17
17
|
l1ChainId: number;
|
|
18
|
-
/** The deployed l1 contract addresses */
|
|
19
|
-
l1Contracts: L1ContractAddresses;
|
|
20
18
|
/** The polling interval viem uses in ms */
|
|
21
19
|
viemPollingIntervalMS: number;
|
|
22
20
|
/** Timeout for HTTP requests to the L1 RPC node in ms. */
|
|
23
21
|
l1HttpTimeoutMS?: number;
|
|
24
|
-
}
|
|
22
|
+
} & L1ContractAddresses;
|
|
25
23
|
|
|
26
24
|
export const l1ReaderConfigMappings: ConfigMappingsType<L1ReaderConfig> = {
|
|
27
|
-
l1Contracts: {
|
|
28
|
-
description: 'The deployed L1 contract addresses',
|
|
29
|
-
nested: l1ContractAddressesMapping,
|
|
30
|
-
},
|
|
31
25
|
l1ChainId: {
|
|
32
26
|
env: 'L1_CHAIN_ID',
|
|
33
|
-
|
|
27
|
+
...optionalNumberConfigHelper(),
|
|
34
28
|
description: 'The chain ID of the ethereum host.',
|
|
35
29
|
},
|
|
36
30
|
l1RpcUrls: {
|
|
@@ -55,6 +49,7 @@ export const l1ReaderConfigMappings: ConfigMappingsType<L1ReaderConfig> = {
|
|
|
55
49
|
description: 'Timeout for HTTP requests to the L1 RPC node in ms.',
|
|
56
50
|
...optionalNumberConfigHelper(),
|
|
57
51
|
},
|
|
52
|
+
...l1ContractAddressesMapping,
|
|
58
53
|
};
|
|
59
54
|
|
|
60
55
|
export function getL1ReaderConfigFromEnv(): L1ReaderConfig {
|
|
@@ -73,7 +73,7 @@ export const l1TxUtilsConfigMappings: ConfigMappingsType<L1TxUtilsConfig> = {
|
|
|
73
73
|
gasLimitBufferPercentage: {
|
|
74
74
|
description: 'How much to increase calculated gas limit by (percentage)',
|
|
75
75
|
env: 'L1_GAS_LIMIT_BUFFER_PERCENTAGE',
|
|
76
|
-
...
|
|
76
|
+
...floatConfigHelper(20),
|
|
77
77
|
},
|
|
78
78
|
maxGwei: {
|
|
79
79
|
description: 'Maximum gas price in gwei to be used for transactions.',
|
|
@@ -90,12 +90,12 @@ export const l1TxUtilsConfigMappings: ConfigMappingsType<L1TxUtilsConfig> = {
|
|
|
90
90
|
priorityFeeBumpPercentage: {
|
|
91
91
|
description: 'How much to increase priority fee by each attempt (percentage)',
|
|
92
92
|
env: 'L1_PRIORITY_FEE_BUMP_PERCENTAGE',
|
|
93
|
-
...
|
|
93
|
+
...floatConfigHelper(20),
|
|
94
94
|
},
|
|
95
95
|
priorityFeeRetryBumpPercentage: {
|
|
96
96
|
description: 'How much to increase priority fee by each retry attempt (percentage)',
|
|
97
97
|
env: 'L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE',
|
|
98
|
-
...
|
|
98
|
+
...floatConfigHelper(50),
|
|
99
99
|
},
|
|
100
100
|
minimumPriorityFeePerGas: {
|
|
101
101
|
description:
|
|
@@ -791,9 +791,6 @@ export class L1FeeAnalyzer {
|
|
|
791
791
|
});
|
|
792
792
|
}
|
|
793
793
|
|
|
794
|
-
/**
|
|
795
|
-
* Gets the minimum value from an array of bigints
|
|
796
|
-
*/
|
|
797
794
|
private minBigInt(values: bigint[]): bigint {
|
|
798
795
|
if (values.length === 0) {
|
|
799
796
|
return 0n;
|
|
@@ -801,3 +798,78 @@ export class L1FeeAnalyzer {
|
|
|
801
798
|
return values.reduce((min, val) => (val < min ? val : min), values[0]);
|
|
802
799
|
}
|
|
803
800
|
}
|
|
801
|
+
|
|
802
|
+
/** Per-block fee data for one mined L1 block, used to diagnose whether a tx was underpriced for it. */
|
|
803
|
+
export interface WindowBlockFees {
|
|
804
|
+
blockNumber: bigint;
|
|
805
|
+
timestamp: bigint;
|
|
806
|
+
baseFeePerGas: bigint;
|
|
807
|
+
/** 75th percentile priority fee among the block's txs (gas-weighted, from eth_feeHistory). */
|
|
808
|
+
p75PriorityFee: bigint;
|
|
809
|
+
/** Minimum priority fee among all included txs — the inclusion bar for that block. */
|
|
810
|
+
minIncludedPriorityFee: bigint;
|
|
811
|
+
blockBlobsFull: boolean;
|
|
812
|
+
includedBlobCount: number;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
/** Safety bound on how far back the window scan walks if the chain head is far ahead of the window. */
|
|
816
|
+
const MAX_WINDOW_SCAN_BLOCKS = 64;
|
|
817
|
+
|
|
818
|
+
/**
|
|
819
|
+
* Reads the already-mined L1 blocks whose timestamps fall in [windowStartS, windowEndS) — the L1
|
|
820
|
+
* inclusion window of an L2 slot — and extracts per-block fee data. Walks block headers to map the
|
|
821
|
+
* window to block numbers, then reads the priority-fee stats from a single eth_feeHistory call
|
|
822
|
+
* (percentile 0 is the cheapest included tx, i.e. the inclusion bar), so no transaction bodies are
|
|
823
|
+
* ever downloaded. Historical reads only, so it never waits on a future block. Returns the blocks in
|
|
824
|
+
* chronological order, [] on error, or the subset mined so far if the window is still in progress.
|
|
825
|
+
* Never throws.
|
|
826
|
+
*/
|
|
827
|
+
export async function captureWindowBlockFees(
|
|
828
|
+
client: ViemClient,
|
|
829
|
+
windowStartS: bigint,
|
|
830
|
+
windowEndS: bigint,
|
|
831
|
+
): Promise<WindowBlockFees[]> {
|
|
832
|
+
try {
|
|
833
|
+
let current = await client.getBlock({ blockTag: 'latest' });
|
|
834
|
+
const inWindow: (typeof current)[] = [];
|
|
835
|
+
let scanned = 0;
|
|
836
|
+
// Walk back from the head, collecting blocks inside the window and skipping any past its end,
|
|
837
|
+
// until we cross below the window start (or hit the safety cap / genesis).
|
|
838
|
+
while (current.timestamp >= windowStartS && scanned < MAX_WINDOW_SCAN_BLOCKS) {
|
|
839
|
+
if (current.timestamp < windowEndS) {
|
|
840
|
+
inWindow.push(current);
|
|
841
|
+
}
|
|
842
|
+
if (current.number === 0n) {
|
|
843
|
+
break;
|
|
844
|
+
}
|
|
845
|
+
current = await client.getBlock({ blockNumber: current.number - 1n });
|
|
846
|
+
scanned++;
|
|
847
|
+
}
|
|
848
|
+
if (inWindow.length === 0) {
|
|
849
|
+
return [];
|
|
850
|
+
}
|
|
851
|
+
inWindow.reverse();
|
|
852
|
+
const newest = inWindow[inWindow.length - 1];
|
|
853
|
+
const feeHistory = await client.getFeeHistory({
|
|
854
|
+
blockCount: Number(newest.number - inWindow[0].number) + 1,
|
|
855
|
+
blockNumber: newest.number,
|
|
856
|
+
rewardPercentiles: [0, 75],
|
|
857
|
+
});
|
|
858
|
+
return inWindow.map(block => {
|
|
859
|
+
const idx = Number(block.number - feeHistory.oldestBlock);
|
|
860
|
+
const [minIncludedPriorityFee, p75PriorityFee] = feeHistory.reward?.[idx] ?? [0n, 0n];
|
|
861
|
+
const blobsInBlock = block.blobGasUsed ? Number(block.blobGasUsed / GAS_PER_BLOB) : 0;
|
|
862
|
+
return {
|
|
863
|
+
blockNumber: block.number,
|
|
864
|
+
timestamp: block.timestamp,
|
|
865
|
+
baseFeePerGas: block.baseFeePerGas ?? 0n,
|
|
866
|
+
p75PriorityFee,
|
|
867
|
+
minIncludedPriorityFee,
|
|
868
|
+
blockBlobsFull: blobsInBlock >= getMaxBlobCapacity(block.timestamp),
|
|
869
|
+
includedBlobCount: blobsInBlock,
|
|
870
|
+
};
|
|
871
|
+
});
|
|
872
|
+
} catch {
|
|
873
|
+
return [];
|
|
874
|
+
}
|
|
875
|
+
}
|