@aztec/sequencer-client 0.0.0-test.0 → 0.0.1-commit.001888fc
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/index.d.ts +1 -1
- package/dest/client/sequencer-client.d.ts +50 -33
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +164 -57
- package/dest/config.d.ts +35 -17
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +150 -81
- package/dest/global_variable_builder/global_builder.d.ts +24 -15
- package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
- package/dest/global_variable_builder/global_builder.js +63 -44
- package/dest/global_variable_builder/index.d.ts +1 -1
- package/dest/index.d.ts +2 -4
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -3
- package/dest/publisher/config.d.ts +48 -27
- package/dest/publisher/config.d.ts.map +1 -1
- package/dest/publisher/config.js +109 -32
- package/dest/publisher/index.d.ts +4 -1
- package/dest/publisher/index.d.ts.map +1 -1
- package/dest/publisher/index.js +3 -0
- package/dest/publisher/l1_tx_failed_store/factory.d.ts +11 -0
- package/dest/publisher/l1_tx_failed_store/factory.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/factory.js +22 -0
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts +59 -0
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.js +1 -0
- package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts +15 -0
- package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.js +34 -0
- package/dest/publisher/l1_tx_failed_store/index.d.ts +4 -0
- package/dest/publisher/l1_tx_failed_store/index.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/index.js +2 -0
- package/dest/publisher/sequencer-publisher-factory.d.ts +52 -0
- package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -0
- package/dest/publisher/sequencer-publisher-factory.js +76 -0
- package/dest/publisher/sequencer-publisher-metrics.d.ts +5 -4
- package/dest/publisher/sequencer-publisher-metrics.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher-metrics.js +34 -62
- package/dest/publisher/sequencer-publisher.d.ts +158 -93
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +1452 -255
- package/dest/sequencer/checkpoint_proposal_job.d.ts +100 -0
- package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -0
- package/dest/sequencer/checkpoint_proposal_job.js +1240 -0
- package/dest/sequencer/checkpoint_voter.d.ts +35 -0
- package/dest/sequencer/checkpoint_voter.d.ts.map +1 -0
- package/dest/sequencer/checkpoint_voter.js +109 -0
- package/dest/sequencer/config.d.ts +7 -1
- package/dest/sequencer/config.d.ts.map +1 -1
- package/dest/sequencer/errors.d.ts +11 -0
- package/dest/sequencer/errors.d.ts.map +1 -0
- package/dest/sequencer/errors.js +15 -0
- package/dest/sequencer/events.d.ts +46 -0
- package/dest/sequencer/events.d.ts.map +1 -0
- package/dest/sequencer/events.js +1 -0
- package/dest/sequencer/index.d.ts +4 -2
- package/dest/sequencer/index.d.ts.map +1 -1
- package/dest/sequencer/index.js +3 -1
- package/dest/sequencer/metrics.d.ts +60 -12
- package/dest/sequencer/metrics.d.ts.map +1 -1
- package/dest/sequencer/metrics.js +283 -67
- package/dest/sequencer/sequencer.d.ts +157 -135
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +966 -523
- package/dest/sequencer/timetable.d.ts +75 -25
- package/dest/sequencer/timetable.d.ts.map +1 -1
- package/dest/sequencer/timetable.js +174 -62
- package/dest/sequencer/types.d.ts +3 -0
- package/dest/sequencer/types.d.ts.map +1 -0
- package/dest/sequencer/types.js +1 -0
- package/dest/sequencer/utils.d.ts +20 -38
- package/dest/sequencer/utils.d.ts.map +1 -1
- package/dest/sequencer/utils.js +12 -47
- package/dest/test/index.d.ts +9 -3
- package/dest/test/index.d.ts.map +1 -1
- package/dest/test/index.js +0 -4
- package/dest/test/mock_checkpoint_builder.d.ts +99 -0
- package/dest/test/mock_checkpoint_builder.d.ts.map +1 -0
- package/dest/test/mock_checkpoint_builder.js +231 -0
- package/dest/test/utils.d.ts +53 -0
- package/dest/test/utils.d.ts.map +1 -0
- package/dest/test/utils.js +104 -0
- package/package.json +46 -45
- package/src/client/sequencer-client.ts +220 -104
- package/src/config.ts +172 -96
- package/src/global_variable_builder/global_builder.ts +85 -55
- package/src/index.ts +1 -3
- package/src/publisher/config.ts +150 -59
- package/src/publisher/index.ts +7 -0
- package/src/publisher/l1_tx_failed_store/factory.ts +32 -0
- package/src/publisher/l1_tx_failed_store/failed_tx_store.ts +55 -0
- package/src/publisher/l1_tx_failed_store/file_store_failed_tx_store.ts +46 -0
- package/src/publisher/l1_tx_failed_store/index.ts +3 -0
- package/src/publisher/sequencer-publisher-factory.ts +124 -0
- package/src/publisher/sequencer-publisher-metrics.ts +33 -63
- package/src/publisher/sequencer-publisher.ts +1266 -311
- package/src/sequencer/README.md +531 -0
- package/src/sequencer/checkpoint_proposal_job.ts +967 -0
- package/src/sequencer/checkpoint_voter.ts +130 -0
- package/src/sequencer/config.ts +8 -0
- package/src/sequencer/errors.ts +21 -0
- package/src/sequencer/events.ts +27 -0
- package/src/sequencer/index.ts +3 -1
- package/src/sequencer/metrics.ts +362 -73
- package/src/sequencer/sequencer.ts +712 -586
- package/src/sequencer/timetable.ts +224 -64
- package/src/sequencer/types.ts +6 -0
- package/src/sequencer/utils.ts +28 -60
- package/src/test/index.ts +11 -5
- package/src/test/mock_checkpoint_builder.ts +323 -0
- package/src/test/utils.ts +167 -0
- package/dest/sequencer/allowed.d.ts +0 -3
- package/dest/sequencer/allowed.d.ts.map +0 -1
- package/dest/sequencer/allowed.js +0 -27
- package/dest/slasher/factory.d.ts +0 -7
- package/dest/slasher/factory.d.ts.map +0 -1
- package/dest/slasher/factory.js +0 -8
- package/dest/slasher/index.d.ts +0 -3
- package/dest/slasher/index.d.ts.map +0 -1
- package/dest/slasher/index.js +0 -2
- package/dest/slasher/slasher_client.d.ts +0 -75
- package/dest/slasher/slasher_client.d.ts.map +0 -1
- package/dest/slasher/slasher_client.js +0 -132
- package/dest/tx_validator/archive_cache.d.ts +0 -14
- package/dest/tx_validator/archive_cache.d.ts.map +0 -1
- package/dest/tx_validator/archive_cache.js +0 -22
- package/dest/tx_validator/gas_validator.d.ts +0 -14
- package/dest/tx_validator/gas_validator.d.ts.map +0 -1
- package/dest/tx_validator/gas_validator.js +0 -78
- package/dest/tx_validator/nullifier_cache.d.ts +0 -16
- package/dest/tx_validator/nullifier_cache.d.ts.map +0 -1
- package/dest/tx_validator/nullifier_cache.js +0 -24
- package/dest/tx_validator/phases_validator.d.ts +0 -12
- package/dest/tx_validator/phases_validator.d.ts.map +0 -1
- package/dest/tx_validator/phases_validator.js +0 -80
- package/dest/tx_validator/test_utils.d.ts +0 -23
- package/dest/tx_validator/test_utils.d.ts.map +0 -1
- package/dest/tx_validator/test_utils.js +0 -26
- package/dest/tx_validator/tx_validator_factory.d.ts +0 -18
- package/dest/tx_validator/tx_validator_factory.d.ts.map +0 -1
- package/dest/tx_validator/tx_validator_factory.js +0 -50
- package/src/sequencer/allowed.ts +0 -36
- package/src/slasher/factory.ts +0 -15
- package/src/slasher/index.ts +0 -2
- package/src/slasher/slasher_client.ts +0 -193
- package/src/tx_validator/archive_cache.ts +0 -28
- package/src/tx_validator/gas_validator.ts +0 -101
- package/src/tx_validator/nullifier_cache.ts +0 -30
- package/src/tx_validator/phases_validator.ts +0 -98
- package/src/tx_validator/test_utils.ts +0 -48
- package/src/tx_validator/tx_validator_factory.ts +0 -120
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type { SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
|
+
import type { Logger } from '@aztec/foundation/log';
|
|
4
|
+
import type { SlasherClientInterface } from '@aztec/slasher';
|
|
5
|
+
import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
6
|
+
import type { ResolvedSequencerConfig } from '@aztec/stdlib/interfaces/server';
|
|
7
|
+
import type { ValidatorClient } from '@aztec/validator-client';
|
|
8
|
+
import { DutyAlreadySignedError } from '@aztec/validator-ha-signer/errors';
|
|
9
|
+
import { DutyType, type SigningContext } from '@aztec/validator-ha-signer/types';
|
|
10
|
+
|
|
11
|
+
import type { TypedDataDefinition } from 'viem';
|
|
12
|
+
|
|
13
|
+
import type { SequencerPublisher } from '../publisher/sequencer-publisher.js';
|
|
14
|
+
import type { SequencerMetrics } from './metrics.js';
|
|
15
|
+
import type { SequencerRollupConstants } from './types.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Handles governance and slashing voting for a given slot.
|
|
19
|
+
*/
|
|
20
|
+
export class CheckpointVoter {
|
|
21
|
+
private slotTimestamp: bigint;
|
|
22
|
+
private governanceSigner: (msg: TypedDataDefinition) => Promise<`0x${string}`>;
|
|
23
|
+
private slashingSigner: (msg: TypedDataDefinition) => Promise<`0x${string}`>;
|
|
24
|
+
|
|
25
|
+
constructor(
|
|
26
|
+
private readonly slot: SlotNumber,
|
|
27
|
+
private readonly publisher: SequencerPublisher,
|
|
28
|
+
private readonly attestorAddress: EthAddress,
|
|
29
|
+
private readonly validatorClient: ValidatorClient,
|
|
30
|
+
private readonly slasherClient: SlasherClientInterface | undefined,
|
|
31
|
+
private readonly l1Constants: SequencerRollupConstants,
|
|
32
|
+
private readonly config: ResolvedSequencerConfig,
|
|
33
|
+
private readonly metrics: SequencerMetrics,
|
|
34
|
+
private readonly log: Logger,
|
|
35
|
+
) {
|
|
36
|
+
this.slotTimestamp = getTimestampForSlot(this.slot, this.l1Constants);
|
|
37
|
+
|
|
38
|
+
// Create separate signers with appropriate duty contexts for governance and slashing votes
|
|
39
|
+
// These use HA protection to ensure only one node signs per slot/duty
|
|
40
|
+
const governanceContext: SigningContext = { slot: this.slot, dutyType: DutyType.GOVERNANCE_VOTE };
|
|
41
|
+
this.governanceSigner = (msg: TypedDataDefinition) =>
|
|
42
|
+
this.validatorClient.signWithAddress(this.attestorAddress, msg, governanceContext).then(s => s.toString());
|
|
43
|
+
|
|
44
|
+
const slashingContext: SigningContext = { slot: this.slot, dutyType: DutyType.SLASHING_VOTE };
|
|
45
|
+
this.slashingSigner = (msg: TypedDataDefinition) =>
|
|
46
|
+
this.validatorClient.signWithAddress(this.attestorAddress, msg, slashingContext).then(s => s.toString());
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Enqueues governance and slashing votes with the publisher.
|
|
51
|
+
* Returns a tuple of promises that resolve to whether each vote was successfully enqueued.
|
|
52
|
+
*/
|
|
53
|
+
enqueueVotes(): [Promise<boolean | undefined>, Promise<boolean | undefined>] {
|
|
54
|
+
try {
|
|
55
|
+
const enqueueGovernancePromise = this.enqueueGovernanceVote();
|
|
56
|
+
const enqueueSlashingPromise = this.enqueueSlashingVote();
|
|
57
|
+
|
|
58
|
+
return [enqueueGovernancePromise, enqueueSlashingPromise];
|
|
59
|
+
} catch (err) {
|
|
60
|
+
this.log.error(`Error enqueueing governance and slashing votes`, err);
|
|
61
|
+
return [Promise.resolve(false), Promise.resolve(false)];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private async enqueueGovernanceVote(): Promise<boolean | undefined> {
|
|
66
|
+
const governanceProposerPayload = this.config.governanceProposerPayload;
|
|
67
|
+
if (!governanceProposerPayload || governanceProposerPayload.isZero()) {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
this.log.info(`Enqueuing vote for ${governanceProposerPayload} governance for slot ${this.slot}`, {
|
|
72
|
+
slot: this.slot,
|
|
73
|
+
governanceProposerPayload: governanceProposerPayload.toString(),
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
return await this.publisher.enqueueGovernanceCastSignal(
|
|
78
|
+
governanceProposerPayload,
|
|
79
|
+
this.slot,
|
|
80
|
+
this.slotTimestamp,
|
|
81
|
+
this.attestorAddress,
|
|
82
|
+
this.governanceSigner,
|
|
83
|
+
);
|
|
84
|
+
} catch (err) {
|
|
85
|
+
if (err instanceof DutyAlreadySignedError) {
|
|
86
|
+
this.log.info(`Governance vote already signed by another node`, {
|
|
87
|
+
slot: this.slot,
|
|
88
|
+
signedByNode: err.signedByNode,
|
|
89
|
+
});
|
|
90
|
+
} else {
|
|
91
|
+
this.log.error(`Error enqueueing governance vote`, err);
|
|
92
|
+
}
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private async enqueueSlashingVote(): Promise<boolean | undefined> {
|
|
98
|
+
try {
|
|
99
|
+
const actions = await this.slasherClient?.getProposerActions(this.slot);
|
|
100
|
+
if (!actions || actions.length === 0) {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
this.log.info(`Enqueuing vote for ${actions.length} slashing actions for slot ${this.slot}`, {
|
|
105
|
+
slot: this.slot,
|
|
106
|
+
actionCount: actions.length,
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
this.metrics.recordSlashingAttempt(actions.length);
|
|
110
|
+
|
|
111
|
+
return await this.publisher.enqueueSlashingActions(
|
|
112
|
+
actions,
|
|
113
|
+
this.slot,
|
|
114
|
+
this.slotTimestamp,
|
|
115
|
+
this.attestorAddress,
|
|
116
|
+
this.slashingSigner,
|
|
117
|
+
);
|
|
118
|
+
} catch (err) {
|
|
119
|
+
if (err instanceof DutyAlreadySignedError) {
|
|
120
|
+
this.log.info(`Slashing vote already signed by another node`, {
|
|
121
|
+
slot: this.slot,
|
|
122
|
+
signedByNode: err.signedByNode,
|
|
123
|
+
});
|
|
124
|
+
} else {
|
|
125
|
+
this.log.error(`Error enqueueing slashing vote`, err);
|
|
126
|
+
}
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
package/src/sequencer/config.ts
CHANGED
|
@@ -1 +1,9 @@
|
|
|
1
|
+
import type { GovernanceProposerContract } from '@aztec/ethereum/contracts';
|
|
2
|
+
import type { RollupContract } from '@aztec/ethereum/contracts/rollup';
|
|
3
|
+
|
|
1
4
|
export { type SequencerConfig } from '@aztec/stdlib/config';
|
|
5
|
+
|
|
6
|
+
export type SequencerContracts = {
|
|
7
|
+
rollupContract: RollupContract;
|
|
8
|
+
governanceProposerContract: GovernanceProposerContract;
|
|
9
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { SequencerState } from './utils.js';
|
|
2
|
+
|
|
3
|
+
export class SequencerTooSlowError extends Error {
|
|
4
|
+
constructor(
|
|
5
|
+
public readonly proposedState: SequencerState,
|
|
6
|
+
public readonly maxAllowedTime: number,
|
|
7
|
+
public readonly currentTime: number,
|
|
8
|
+
) {
|
|
9
|
+
super(
|
|
10
|
+
`Too far into slot for ${proposedState} (time into slot ${currentTime}s greater than ${maxAllowedTime}s allowance)`,
|
|
11
|
+
);
|
|
12
|
+
this.name = 'SequencerTooSlowError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class SequencerInterruptedError extends Error {
|
|
17
|
+
constructor() {
|
|
18
|
+
super(`Sequencer was interrupted`);
|
|
19
|
+
this.name = 'SequencerInterruptedError';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
|
|
3
|
+
import type { Action } from '../publisher/sequencer-publisher.js';
|
|
4
|
+
import type { SequencerState } from './utils.js';
|
|
5
|
+
|
|
6
|
+
export type SequencerEvents = {
|
|
7
|
+
['state-changed']: (args: {
|
|
8
|
+
oldState: SequencerState;
|
|
9
|
+
newState: SequencerState;
|
|
10
|
+
secondsIntoSlot?: number;
|
|
11
|
+
slot?: SlotNumber;
|
|
12
|
+
}) => void;
|
|
13
|
+
['proposer-rollup-check-failed']: (args: { reason: string; slot: SlotNumber }) => void;
|
|
14
|
+
['block-tx-count-check-failed']: (args: { minTxs: number; availableTxs: number; slot: SlotNumber }) => void;
|
|
15
|
+
['block-build-failed']: (args: { reason: string; slot: SlotNumber }) => void;
|
|
16
|
+
['block-proposed']: (args: { blockNumber: BlockNumber; slot: SlotNumber }) => void;
|
|
17
|
+
['checkpoint-empty']: (args: { slot: SlotNumber }) => void;
|
|
18
|
+
['checkpoint-publish-failed']: (args: {
|
|
19
|
+
slot: SlotNumber;
|
|
20
|
+
successfulActions?: Action[];
|
|
21
|
+
failedActions?: Action[];
|
|
22
|
+
sentActions?: Action[];
|
|
23
|
+
expiredActions?: Action[];
|
|
24
|
+
}) => void;
|
|
25
|
+
['checkpoint-published']: (args: { checkpoint: CheckpointNumber; slot: SlotNumber }) => void;
|
|
26
|
+
['checkpoint-error']: (args: { error: Error }) => void;
|
|
27
|
+
};
|