@aztec/sequencer-client 0.72.1 → 0.74.0
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/sequencer-client.d.ts +11 -6
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +46 -10
- package/dest/config.d.ts +1 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +3 -4
- package/dest/publisher/config.d.ts +5 -0
- package/dest/publisher/config.d.ts.map +1 -1
- package/dest/publisher/config.js +9 -2
- package/dest/publisher/index.d.ts +1 -1
- package/dest/publisher/index.d.ts.map +1 -1
- package/dest/publisher/index.js +2 -2
- package/dest/publisher/{l1-publisher-metrics.d.ts → sequencer-publisher-metrics.d.ts} +6 -2
- package/dest/publisher/sequencer-publisher-metrics.d.ts.map +1 -0
- package/dest/publisher/sequencer-publisher-metrics.js +111 -0
- package/dest/publisher/sequencer-publisher.d.ts +163 -0
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -0
- package/dest/publisher/sequencer-publisher.js +528 -0
- package/dest/sequencer/allowed.d.ts +1 -1
- package/dest/sequencer/allowed.d.ts.map +1 -1
- package/dest/sequencer/allowed.js +4 -4
- package/dest/sequencer/metrics.d.ts +1 -1
- package/dest/sequencer/metrics.d.ts.map +1 -1
- package/dest/sequencer/metrics.js +3 -4
- package/dest/sequencer/sequencer.d.ts +17 -10
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +103 -109
- package/dest/sequencer/utils.d.ts +1 -1
- package/dest/sequencer/utils.d.ts.map +1 -1
- package/dest/sequencer/utils.js +3 -3
- package/dest/slasher/factory.d.ts +2 -2
- package/dest/slasher/factory.d.ts.map +1 -1
- package/dest/slasher/factory.js +2 -2
- package/dest/slasher/slasher_client.d.ts +4 -4
- package/dest/slasher/slasher_client.d.ts.map +1 -1
- package/dest/slasher/slasher_client.js +38 -26
- package/dest/test/index.d.ts +3 -3
- package/dest/test/index.d.ts.map +1 -1
- package/dest/test/index.js +1 -2
- package/dest/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/tx_validator/gas_validator.js +4 -3
- package/dest/tx_validator/test_utils.d.ts +4 -4
- package/dest/tx_validator/test_utils.d.ts.map +1 -1
- package/dest/tx_validator/test_utils.js +3 -3
- package/package.json +21 -20
- package/src/client/sequencer-client.ts +81 -14
- package/src/config.ts +3 -3
- package/src/publisher/config.ts +13 -1
- package/src/publisher/index.ts +1 -1
- package/src/publisher/{l1-publisher-metrics.ts → sequencer-publisher-metrics.ts} +41 -2
- package/src/publisher/sequencer-publisher.ts +710 -0
- package/src/sequencer/allowed.ts +3 -3
- package/src/sequencer/metrics.ts +2 -3
- package/src/sequencer/sequencer.ts +138 -125
- package/src/sequencer/utils.ts +5 -2
- package/src/slasher/factory.ts +3 -3
- package/src/slasher/slasher_client.ts +44 -30
- package/src/test/index.ts +2 -4
- package/src/tx_validator/gas_validator.ts +5 -4
- package/src/tx_validator/test_utils.ts +5 -5
- package/dest/publisher/l1-publisher-metrics.d.ts.map +0 -1
- package/dest/publisher/l1-publisher-metrics.js +0 -85
- package/dest/publisher/l1-publisher.d.ts +0 -195
- package/dest/publisher/l1-publisher.d.ts.map +0 -1
- package/dest/publisher/l1-publisher.js +0 -930
- package/dest/test/test-l1-publisher.d.ts +0 -9
- package/dest/test/test-l1-publisher.d.ts.map +0 -1
- package/dest/test/test-l1-publisher.js +0 -11
- package/src/publisher/l1-publisher.ts +0 -1288
- package/src/test/test-l1-publisher.ts +0 -20
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
import { type BlobSinkClientInterface } from '@aztec/blob-sink/client';
|
|
2
2
|
import { type L1ToL2MessageSource, type L2BlockSource, type WorldStateSynchronizer } from '@aztec/circuit-types';
|
|
3
|
-
import { type ContractDataSource } from '@aztec/circuits.js';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { type AztecAddress, type ContractDataSource } from '@aztec/circuits.js';
|
|
4
|
+
import { EpochCache } from '@aztec/epoch-cache';
|
|
5
|
+
import {
|
|
6
|
+
ForwarderContract,
|
|
7
|
+
GovernanceProposerContract,
|
|
8
|
+
L1TxUtilsWithBlobs,
|
|
9
|
+
RollupContract,
|
|
10
|
+
SlashingProposerContract,
|
|
11
|
+
createEthereumChain,
|
|
12
|
+
createL1Clients,
|
|
13
|
+
isAnvilTestChain,
|
|
14
|
+
} from '@aztec/ethereum';
|
|
15
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
16
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
6
17
|
import { type DateProvider } from '@aztec/foundation/timer';
|
|
7
18
|
import { type P2P } from '@aztec/p2p';
|
|
8
19
|
import { LightweightBlockBuilderFactory } from '@aztec/prover-client/block-builder';
|
|
@@ -12,7 +23,7 @@ import { type ValidatorClient } from '@aztec/validator-client';
|
|
|
12
23
|
|
|
13
24
|
import { type SequencerClientConfig } from '../config.js';
|
|
14
25
|
import { GlobalVariableBuilder } from '../global_variable_builder/index.js';
|
|
15
|
-
import {
|
|
26
|
+
import { SequencerPublisher } from '../publisher/index.js';
|
|
16
27
|
import { Sequencer, type SequencerConfig } from '../sequencer/index.js';
|
|
17
28
|
import { type SlasherClient } from '../slasher/index.js';
|
|
18
29
|
|
|
@@ -46,9 +57,11 @@ export class SequencerClient {
|
|
|
46
57
|
l2BlockSource: L2BlockSource;
|
|
47
58
|
l1ToL2MessageSource: L1ToL2MessageSource;
|
|
48
59
|
telemetry: TelemetryClient;
|
|
49
|
-
publisher?:
|
|
60
|
+
publisher?: SequencerPublisher;
|
|
50
61
|
blobSinkClient?: BlobSinkClientInterface;
|
|
51
62
|
dateProvider: DateProvider;
|
|
63
|
+
epochCache?: EpochCache;
|
|
64
|
+
l1TxUtils?: L1TxUtilsWithBlobs;
|
|
52
65
|
},
|
|
53
66
|
) {
|
|
54
67
|
const {
|
|
@@ -61,18 +74,68 @@ export class SequencerClient {
|
|
|
61
74
|
l1ToL2MessageSource,
|
|
62
75
|
telemetry: telemetryClient,
|
|
63
76
|
} = deps;
|
|
77
|
+
const { l1RpcUrl: rpcUrl, l1ChainId: chainId, publisherPrivateKey } = config;
|
|
78
|
+
const chain = createEthereumChain(rpcUrl, chainId);
|
|
79
|
+
const log = createLogger('sequencer-client');
|
|
80
|
+
const { publicClient, walletClient } = createL1Clients(rpcUrl, publisherPrivateKey, chain.chainInfo);
|
|
81
|
+
const l1TxUtils = deps.l1TxUtils ?? new L1TxUtilsWithBlobs(publicClient, walletClient, log, config);
|
|
82
|
+
const rollupContract = new RollupContract(publicClient, config.l1Contracts.rollupAddress.toString());
|
|
83
|
+
const [l1GenesisTime, slotDuration] = await Promise.all([
|
|
84
|
+
rollupContract.getL1GenesisTime(),
|
|
85
|
+
rollupContract.getSlotDuration(),
|
|
86
|
+
] as const);
|
|
87
|
+
const forwarderContract =
|
|
88
|
+
config.customForwarderContractAddress && config.customForwarderContractAddress !== EthAddress.ZERO
|
|
89
|
+
? new ForwarderContract(
|
|
90
|
+
publicClient,
|
|
91
|
+
config.customForwarderContractAddress.toString(),
|
|
92
|
+
config.l1Contracts.rollupAddress.toString(),
|
|
93
|
+
)
|
|
94
|
+
: await ForwarderContract.create(
|
|
95
|
+
walletClient.account.address,
|
|
96
|
+
walletClient,
|
|
97
|
+
publicClient,
|
|
98
|
+
log,
|
|
99
|
+
config.l1Contracts.rollupAddress.toString(),
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const governanceProposerContract = new GovernanceProposerContract(
|
|
103
|
+
publicClient,
|
|
104
|
+
config.l1Contracts.governanceProposerAddress.toString(),
|
|
105
|
+
);
|
|
106
|
+
const slashingProposerAddress = await rollupContract.getSlashingProposerAddress();
|
|
107
|
+
const slashingProposerContract = new SlashingProposerContract(publicClient, slashingProposerAddress.toString());
|
|
108
|
+
const epochCache =
|
|
109
|
+
deps.epochCache ??
|
|
110
|
+
(await EpochCache.create(
|
|
111
|
+
config.l1Contracts.rollupAddress,
|
|
112
|
+
{
|
|
113
|
+
l1RpcUrl: rpcUrl,
|
|
114
|
+
l1ChainId: chainId,
|
|
115
|
+
viemPollingIntervalMS: config.viemPollingIntervalMS,
|
|
116
|
+
aztecSlotDuration: config.aztecSlotDuration,
|
|
117
|
+
ethereumSlotDuration: config.ethereumSlotDuration,
|
|
118
|
+
aztecEpochDuration: config.aztecEpochDuration,
|
|
119
|
+
},
|
|
120
|
+
{ dateProvider: deps.dateProvider },
|
|
121
|
+
));
|
|
122
|
+
|
|
64
123
|
const publisher =
|
|
65
|
-
deps.publisher ??
|
|
124
|
+
deps.publisher ??
|
|
125
|
+
new SequencerPublisher(config, {
|
|
126
|
+
l1TxUtils,
|
|
127
|
+
telemetry: telemetryClient,
|
|
128
|
+
blobSinkClient: deps.blobSinkClient,
|
|
129
|
+
rollupContract,
|
|
130
|
+
epochCache,
|
|
131
|
+
forwarderContract,
|
|
132
|
+
governanceProposerContract,
|
|
133
|
+
slashingProposerContract,
|
|
134
|
+
});
|
|
66
135
|
const globalsBuilder = new GlobalVariableBuilder(config);
|
|
67
136
|
|
|
68
137
|
const publicProcessorFactory = new PublicProcessorFactory(contractDataSource, deps.dateProvider, telemetryClient);
|
|
69
138
|
|
|
70
|
-
const rollup = publisher.getRollupContract();
|
|
71
|
-
const [l1GenesisTime, slotDuration] = await Promise.all([
|
|
72
|
-
rollup.read.GENESIS_TIME(),
|
|
73
|
-
rollup.read.SLOT_DURATION(),
|
|
74
|
-
] as const);
|
|
75
|
-
|
|
76
139
|
const ethereumSlotDuration = config.ethereumSlotDuration;
|
|
77
140
|
|
|
78
141
|
// When running in anvil, assume we can post a tx up until the very last second of an L1 slot.
|
|
@@ -117,7 +180,7 @@ export class SequencerClient {
|
|
|
117
180
|
* @param config - New parameters.
|
|
118
181
|
*/
|
|
119
182
|
public updateSequencerConfig(config: SequencerConfig) {
|
|
120
|
-
this.sequencer.updateConfig(config);
|
|
183
|
+
return this.sequencer.updateConfig(config);
|
|
121
184
|
}
|
|
122
185
|
|
|
123
186
|
/**
|
|
@@ -143,7 +206,11 @@ export class SequencerClient {
|
|
|
143
206
|
return this.sequencer.coinbase;
|
|
144
207
|
}
|
|
145
208
|
|
|
146
|
-
get feeRecipient() {
|
|
209
|
+
get feeRecipient(): AztecAddress {
|
|
147
210
|
return this.sequencer.feeRecipient;
|
|
148
211
|
}
|
|
212
|
+
|
|
213
|
+
get forwarderAddress(): EthAddress {
|
|
214
|
+
return this.sequencer.getForwarderAddress();
|
|
215
|
+
}
|
|
149
216
|
}
|
package/src/config.ts
CHANGED
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
booleanConfigHelper,
|
|
12
12
|
getConfigFromMappings,
|
|
13
13
|
numberConfigHelper,
|
|
14
|
+
pickConfigMappings,
|
|
14
15
|
} from '@aztec/foundation/config';
|
|
15
|
-
import { pickConfigMappings } from '@aztec/foundation/config';
|
|
16
16
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
17
17
|
|
|
18
18
|
import {
|
|
@@ -41,7 +41,7 @@ export type SequencerClientConfig = PublisherConfig &
|
|
|
41
41
|
SequencerConfig &
|
|
42
42
|
L1ReaderConfig &
|
|
43
43
|
ChainConfig &
|
|
44
|
-
Pick<L1ContractsConfig, 'ethereumSlotDuration'>;
|
|
44
|
+
Pick<L1ContractsConfig, 'ethereumSlotDuration' | 'aztecSlotDuration' | 'aztecEpochDuration'>;
|
|
45
45
|
|
|
46
46
|
export const sequencerConfigMappings: ConfigMappingsType<SequencerConfig> = {
|
|
47
47
|
transactionPollingIntervalMS: {
|
|
@@ -138,7 +138,7 @@ export const sequencerClientConfigMappings: ConfigMappingsType<SequencerClientCo
|
|
|
138
138
|
...getTxSenderConfigMappings('SEQ'),
|
|
139
139
|
...getPublisherConfigMappings('SEQ'),
|
|
140
140
|
...chainConfigMappings,
|
|
141
|
-
...pickConfigMappings(l1ContractsConfigMappings, ['ethereumSlotDuration']),
|
|
141
|
+
...pickConfigMappings(l1ContractsConfigMappings, ['ethereumSlotDuration', 'aztecSlotDuration', 'aztecEpochDuration']),
|
|
142
142
|
};
|
|
143
143
|
|
|
144
144
|
/**
|
package/src/publisher/config.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type L1ReaderConfig, type L1TxUtilsConfig, NULL_KEY, l1TxUtilsConfigMappings } from '@aztec/ethereum';
|
|
2
2
|
import { type ConfigMappingsType, getConfigFromMappings, numberConfigHelper } from '@aztec/foundation/config';
|
|
3
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* The configuration of the rollup transaction publisher.
|
|
@@ -14,6 +15,11 @@ export type TxSenderConfig = L1ReaderConfig & {
|
|
|
14
15
|
* The number of confirmations required.
|
|
15
16
|
*/
|
|
16
17
|
requiredConfirmations: number;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The address of the custom forwarder contract.
|
|
21
|
+
*/
|
|
22
|
+
customForwarderContractAddress: EthAddress;
|
|
17
23
|
};
|
|
18
24
|
|
|
19
25
|
/**
|
|
@@ -44,6 +50,12 @@ export const getTxSenderConfigMappings: (
|
|
|
44
50
|
defaultValue: 31337,
|
|
45
51
|
description: 'The chain ID of the ethereum host.',
|
|
46
52
|
},
|
|
53
|
+
customForwarderContractAddress: {
|
|
54
|
+
env: `CUSTOM_FORWARDER_CONTRACT_ADDRESS`,
|
|
55
|
+
parseEnv: (val: string) => EthAddress.fromString(val),
|
|
56
|
+
description: 'The address of the custom forwarder contract.',
|
|
57
|
+
defaultValue: EthAddress.ZERO,
|
|
58
|
+
},
|
|
47
59
|
publisherPrivateKey: {
|
|
48
60
|
env: `${scope}_PUBLISHER_PRIVATE_KEY`,
|
|
49
61
|
description: 'The private key to be used by the publisher.',
|
|
@@ -78,7 +90,7 @@ export const getPublisherConfigMappings: (
|
|
|
78
90
|
},
|
|
79
91
|
...l1TxUtilsConfigMappings,
|
|
80
92
|
blobSinkUrl: {
|
|
81
|
-
env:
|
|
93
|
+
env: 'BLOB_SINK_URL',
|
|
82
94
|
description: 'The URL of the blob sink.',
|
|
83
95
|
parseEnv: (val?: string) => val,
|
|
84
96
|
},
|
package/src/publisher/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { SequencerPublisher } from './sequencer-publisher.js';
|
|
@@ -12,7 +12,7 @@ import { formatEther } from 'viem/utils';
|
|
|
12
12
|
|
|
13
13
|
export type L1TxType = 'submitProof' | 'process' | 'claimEpochProofRight';
|
|
14
14
|
|
|
15
|
-
export class
|
|
15
|
+
export class SequencerPublisherMetrics {
|
|
16
16
|
private gasPrice: Histogram;
|
|
17
17
|
|
|
18
18
|
private txCount: UpDownCounter;
|
|
@@ -23,7 +23,12 @@ export class L1PublisherMetrics {
|
|
|
23
23
|
private txBlobDataGasUsed: Histogram;
|
|
24
24
|
private txBlobDataGasCost: Histogram;
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
private readonly blobCountHistogram: Histogram;
|
|
27
|
+
private readonly blobInclusionBlocksHistogram: Histogram;
|
|
28
|
+
private readonly blobTxSuccessCounter: UpDownCounter;
|
|
29
|
+
private readonly blobTxFailureCounter: UpDownCounter;
|
|
30
|
+
|
|
31
|
+
constructor(client: TelemetryClient, name = 'SequencerPublisher') {
|
|
27
32
|
const meter = client.getMeter(name);
|
|
28
33
|
|
|
29
34
|
this.gasPrice = meter.createHistogram(Metrics.L1_PUBLISHER_GAS_PRICE, {
|
|
@@ -71,6 +76,26 @@ export class L1PublisherMetrics {
|
|
|
71
76
|
unit: 'gwei',
|
|
72
77
|
valueType: ValueType.INT,
|
|
73
78
|
});
|
|
79
|
+
|
|
80
|
+
this.blobCountHistogram = meter.createHistogram(Metrics.L1_PUBLISHER_BLOB_COUNT, {
|
|
81
|
+
description: 'Number of blobs in L1 transactions',
|
|
82
|
+
unit: 'blobs',
|
|
83
|
+
valueType: ValueType.INT,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
this.blobInclusionBlocksHistogram = meter.createHistogram(Metrics.L1_PUBLISHER_BLOB_INCLUSION_BLOCKS, {
|
|
87
|
+
description: 'Number of L1 blocks between blob tx submission and inclusion',
|
|
88
|
+
unit: 'blocks',
|
|
89
|
+
valueType: ValueType.INT,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
this.blobTxSuccessCounter = meter.createUpDownCounter(Metrics.L1_PUBLISHER_BLOB_TX_SUCCESS, {
|
|
93
|
+
description: 'Number of successful L1 transactions with blobs',
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
this.blobTxFailureCounter = meter.createUpDownCounter(Metrics.L1_PUBLISHER_BLOB_TX_FAILURE, {
|
|
97
|
+
description: 'Number of failed L1 transactions with blobs',
|
|
98
|
+
});
|
|
74
99
|
}
|
|
75
100
|
|
|
76
101
|
recordFailedTx(txType: L1TxType) {
|
|
@@ -78,6 +103,10 @@ export class L1PublisherMetrics {
|
|
|
78
103
|
[Attributes.L1_TX_TYPE]: txType,
|
|
79
104
|
[Attributes.OK]: false,
|
|
80
105
|
});
|
|
106
|
+
|
|
107
|
+
if (txType === 'process') {
|
|
108
|
+
this.blobTxFailureCounter.add(1);
|
|
109
|
+
}
|
|
81
110
|
}
|
|
82
111
|
|
|
83
112
|
recordSubmitProof(durationMs: number, stats: L1PublishProofStats) {
|
|
@@ -86,6 +115,16 @@ export class L1PublisherMetrics {
|
|
|
86
115
|
|
|
87
116
|
recordProcessBlockTx(durationMs: number, stats: L1PublishBlockStats) {
|
|
88
117
|
this.recordTx('process', durationMs, stats);
|
|
118
|
+
|
|
119
|
+
if (stats.blobCount && stats.blobCount > 0) {
|
|
120
|
+
this.blobCountHistogram.record(stats.blobCount);
|
|
121
|
+
|
|
122
|
+
if (stats.inclusionBlocks !== undefined) {
|
|
123
|
+
this.blobInclusionBlocksHistogram.record(stats.inclusionBlocks);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
this.blobTxSuccessCounter.add(1);
|
|
127
|
+
}
|
|
89
128
|
}
|
|
90
129
|
|
|
91
130
|
recordClaimEpochProofRightTx(durationMs: number, stats: L1PublishStats) {
|