@aztec/sequencer-client 1.0.0-nightly.20250708 → 1.0.0-nightly.20250710
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/publisher/index.d.ts +1 -1
- package/dest/publisher/index.d.ts.map +1 -1
- package/dest/publisher/index.js +1 -1
- package/dest/publisher/sequencer-publisher.d.ts +7 -4
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +95 -38
- package/dest/sequencer/sequencer.d.ts +3 -1
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +5 -7
- package/package.json +26 -26
- package/src/publisher/index.ts +1 -1
- package/src/publisher/sequencer-publisher.ts +84 -34
- package/src/sequencer/sequencer.ts +17 -7
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { SequencerPublisher } from './sequencer-publisher.js';
|
|
1
|
+
export { SequencerPublisher, VoteType } from './sequencer-publisher.js';
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/publisher/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/publisher/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC"}
|
package/dest/publisher/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { SequencerPublisher } from './sequencer-publisher.js';
|
|
1
|
+
export { SequencerPublisher, VoteType } from './sequencer-publisher.js';
|
|
@@ -23,14 +23,15 @@ interface RequestWithExpiry {
|
|
|
23
23
|
lastValidL2Slot: bigint;
|
|
24
24
|
gasConfig?: Pick<L1GasConfig, 'txTimeoutAt' | 'gasLimit'>;
|
|
25
25
|
blobConfig?: L1BlobInputs;
|
|
26
|
-
|
|
26
|
+
checkSuccess: (request: L1TxRequest, result?: {
|
|
27
27
|
receipt: TransactionReceipt;
|
|
28
28
|
gasPrice: GasPrice;
|
|
29
29
|
stats?: TransactionStats;
|
|
30
30
|
errorMsg?: string;
|
|
31
|
-
}) =>
|
|
31
|
+
}) => boolean;
|
|
32
32
|
}
|
|
33
33
|
export declare class SequencerPublisher {
|
|
34
|
+
private config;
|
|
34
35
|
private interrupted;
|
|
35
36
|
private metrics;
|
|
36
37
|
epochCache: EpochCache;
|
|
@@ -90,7 +91,9 @@ export declare class SequencerPublisher {
|
|
|
90
91
|
stats?: undefined;
|
|
91
92
|
};
|
|
92
93
|
expiredActions: Action[];
|
|
93
|
-
|
|
94
|
+
sentActions: Action[];
|
|
95
|
+
successfulActions: Action[];
|
|
96
|
+
failedActions: Action[];
|
|
94
97
|
} | undefined>;
|
|
95
98
|
private callbackBundledTransactions;
|
|
96
99
|
/**
|
|
@@ -133,7 +136,7 @@ export declare class SequencerPublisher {
|
|
|
133
136
|
* @param voteType - The type of vote to cast.
|
|
134
137
|
* @returns True if the vote was successfully enqueued, false otherwise.
|
|
135
138
|
*/
|
|
136
|
-
enqueueCastVote(slotNumber: bigint, timestamp: bigint, voteType: VoteType): Promise<boolean>;
|
|
139
|
+
enqueueCastVote(slotNumber: bigint, timestamp: bigint, voteType: VoteType, signerAddress: EthAddress, signer: (msg: `0x${string}`) => Promise<`0x${string}`>): Promise<boolean>;
|
|
137
140
|
/**
|
|
138
141
|
* Proposes a L2 block on L1.
|
|
139
142
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequencer-publisher.d.ts","sourceRoot":"","sources":["../../src/publisher/sequencer-publisher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,KAAK,uBAAuB,EAAwB,MAAM,yBAAyB,CAAC;AAC7F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,kBAAkB,EAClB,KAAK,QAAQ,EACb,KAAK,0BAA0B,EAE/B,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,WAAW,EAGhB,cAAc,EACd,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,EAKtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAGjF,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAS,MAAM,yBAAyB,CAAC;AAE9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,EAAE,KAAK,mBAAmB,EAAkB,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACpF,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAGnF,OAAO,EAAE,KAAK,kBAAkB,
|
|
1
|
+
{"version":3,"file":"sequencer-publisher.d.ts","sourceRoot":"","sources":["../../src/publisher/sequencer-publisher.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,12 +6,12 @@ import { toHex as toPaddedHex } from '@aztec/foundation/bigint-buffer';
|
|
|
6
6
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
7
7
|
import { createLogger } from '@aztec/foundation/log';
|
|
8
8
|
import { Timer } from '@aztec/foundation/timer';
|
|
9
|
-
import { RollupAbi } from '@aztec/l1-artifacts';
|
|
9
|
+
import { EmpireBaseAbi, ErrorsAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
10
10
|
import { CommitteeAttestation } from '@aztec/stdlib/block';
|
|
11
11
|
import { ConsensusPayload, SignatureDomainSeparator, getHashedSignaturePayload } from '@aztec/stdlib/p2p';
|
|
12
12
|
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
13
13
|
import pick from 'lodash.pick';
|
|
14
|
-
import { encodeFunctionData, toHex } from 'viem';
|
|
14
|
+
import { encodeFunctionData, getAbiItem, toEventSelector, toHex } from 'viem';
|
|
15
15
|
import { SequencerPublisherMetrics } from './sequencer-publisher-metrics.js';
|
|
16
16
|
export var VoteType = /*#__PURE__*/ function(VoteType) {
|
|
17
17
|
VoteType[VoteType["GOVERNANCE"] = 0] = "GOVERNANCE";
|
|
@@ -19,21 +19,19 @@ export var VoteType = /*#__PURE__*/ function(VoteType) {
|
|
|
19
19
|
return VoteType;
|
|
20
20
|
}({});
|
|
21
21
|
export class SequencerPublisher {
|
|
22
|
-
|
|
22
|
+
config;
|
|
23
|
+
interrupted;
|
|
23
24
|
metrics;
|
|
24
25
|
epochCache;
|
|
25
26
|
dateProvider;
|
|
26
|
-
governanceLog
|
|
27
|
+
governanceLog;
|
|
27
28
|
governanceProposerAddress;
|
|
28
|
-
governancePayload
|
|
29
|
-
slashingLog
|
|
29
|
+
governancePayload;
|
|
30
|
+
slashingLog;
|
|
30
31
|
slashingProposerAddress;
|
|
31
|
-
getSlashPayload
|
|
32
|
-
myLastVotes
|
|
33
|
-
|
|
34
|
-
[1]: 0n
|
|
35
|
-
};
|
|
36
|
-
log = createLogger('sequencer:publisher');
|
|
32
|
+
getSlashPayload;
|
|
33
|
+
myLastVotes;
|
|
34
|
+
log;
|
|
37
35
|
ethereumSlotDuration;
|
|
38
36
|
blobSinkClient;
|
|
39
37
|
// @note - with blobs, the below estimate seems too large.
|
|
@@ -48,8 +46,20 @@ export class SequencerPublisher {
|
|
|
48
46
|
rollupContract;
|
|
49
47
|
govProposerContract;
|
|
50
48
|
slashingProposerContract;
|
|
51
|
-
requests
|
|
49
|
+
requests;
|
|
52
50
|
constructor(config, deps){
|
|
51
|
+
this.config = config;
|
|
52
|
+
this.interrupted = false;
|
|
53
|
+
this.governanceLog = createLogger('sequencer:publisher:governance');
|
|
54
|
+
this.governancePayload = EthAddress.ZERO;
|
|
55
|
+
this.slashingLog = createLogger('sequencer:publisher:slashing');
|
|
56
|
+
this.getSlashPayload = undefined;
|
|
57
|
+
this.myLastVotes = {
|
|
58
|
+
[0]: 0n,
|
|
59
|
+
[1]: 0n
|
|
60
|
+
};
|
|
61
|
+
this.log = createLogger('sequencer:publisher');
|
|
62
|
+
this.requests = [];
|
|
53
63
|
this.ethereumSlotDuration = BigInt(config.ethereumSlotDuration);
|
|
54
64
|
this.epochCache = deps.epochCache;
|
|
55
65
|
this.dateProvider = deps.dateProvider;
|
|
@@ -142,11 +152,13 @@ export class SequencerPublisher {
|
|
|
142
152
|
validRequests: validRequests.map((request)=>request.action)
|
|
143
153
|
});
|
|
144
154
|
const result = await Multicall3.forward(validRequests.map((request)=>request.request), this.l1TxUtils, gasConfig, blobConfig, this.rollupContract.address, this.log);
|
|
145
|
-
this.callbackBundledTransactions(validRequests, result);
|
|
155
|
+
const { successfulActions = [], failedActions = [] } = this.callbackBundledTransactions(validRequests, result);
|
|
146
156
|
return {
|
|
147
157
|
result,
|
|
148
158
|
expiredActions,
|
|
149
|
-
validActions
|
|
159
|
+
sentActions: validActions,
|
|
160
|
+
successfulActions,
|
|
161
|
+
failedActions
|
|
150
162
|
};
|
|
151
163
|
} catch (err) {
|
|
152
164
|
const viemError = formatViemError(err);
|
|
@@ -161,17 +173,30 @@ export class SequencerPublisher {
|
|
|
161
173
|
}
|
|
162
174
|
}
|
|
163
175
|
callbackBundledTransactions(requests, result) {
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
176
|
+
const actionsListStr = requests.map((r)=>r.action).join(', ');
|
|
177
|
+
if (result instanceof FormattedViemError) {
|
|
178
|
+
this.log.error(`Failed to publish bundled transactions (${actionsListStr})`, result);
|
|
179
|
+
return {
|
|
180
|
+
failedActions: requests.map((r)=>r.action)
|
|
181
|
+
};
|
|
182
|
+
} else {
|
|
183
|
+
this.log.verbose(`Published bundled transactions (${actionsListStr})`, {
|
|
184
|
+
result,
|
|
185
|
+
requests
|
|
186
|
+
});
|
|
187
|
+
const successfulActions = [];
|
|
188
|
+
const failedActions = [];
|
|
189
|
+
for (const request of requests){
|
|
190
|
+
if (request.checkSuccess(request.request, result)) {
|
|
191
|
+
successfulActions.push(request.action);
|
|
192
|
+
} else {
|
|
193
|
+
failedActions.push(request.action);
|
|
194
|
+
}
|
|
171
195
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
196
|
+
return {
|
|
197
|
+
successfulActions,
|
|
198
|
+
failedActions
|
|
199
|
+
};
|
|
175
200
|
}
|
|
176
201
|
}
|
|
177
202
|
/**
|
|
@@ -280,7 +305,7 @@ export class SequencerPublisher {
|
|
|
280
305
|
const committee = await this.rollupContract.getCurrentEpochCommittee();
|
|
281
306
|
return committee?.map(EthAddress.fromString);
|
|
282
307
|
}
|
|
283
|
-
async enqueueCastVoteHelper(slotNumber, timestamp, voteType, payload, base) {
|
|
308
|
+
async enqueueCastVoteHelper(slotNumber, timestamp, voteType, payload, base, signerAddress, signer) {
|
|
284
309
|
if (this.myLastVotes[voteType] >= slotNumber) {
|
|
285
310
|
return false;
|
|
286
311
|
}
|
|
@@ -295,13 +320,24 @@ export class SequencerPublisher {
|
|
|
295
320
|
const cachedLastVote = this.myLastVotes[voteType];
|
|
296
321
|
this.myLastVotes[voteType] = slotNumber;
|
|
297
322
|
const action = voteType === 0 ? 'governance-vote' : 'slashing-vote';
|
|
298
|
-
const request = await base.createVoteRequestWithSignature(payload.toString(), this.
|
|
323
|
+
const request = await base.createVoteRequestWithSignature(payload.toString(), this.config.l1ChainId, signerAddress.toString(), signer);
|
|
299
324
|
this.log.debug(`Created ${action} request with signature`, {
|
|
300
325
|
request,
|
|
301
326
|
round,
|
|
302
327
|
signer: this.l1TxUtils.client.account?.address,
|
|
303
328
|
lastValidL2Slot: slotNumber
|
|
304
329
|
});
|
|
330
|
+
try {
|
|
331
|
+
await this.l1TxUtils.simulate(request, {
|
|
332
|
+
time: timestamp
|
|
333
|
+
}, [], ErrorsAbi);
|
|
334
|
+
this.log.debug(`Simulation for ${action} at slot ${slotNumber} succeeded`, {
|
|
335
|
+
request
|
|
336
|
+
});
|
|
337
|
+
} catch (err) {
|
|
338
|
+
this.log.warn(`Failed simulation for ${action} at slot ${slotNumber} (enqueuing the action anyway)`, err);
|
|
339
|
+
// Yes, we enqueue the request anyway, in case there was a bug with the simulation itself
|
|
340
|
+
}
|
|
305
341
|
this.addRequest({
|
|
306
342
|
gasConfig: {
|
|
307
343
|
gasLimit: SequencerPublisher.VOTE_GAS_GUESS
|
|
@@ -309,11 +345,24 @@ export class SequencerPublisher {
|
|
|
309
345
|
action,
|
|
310
346
|
request,
|
|
311
347
|
lastValidL2Slot: slotNumber,
|
|
312
|
-
|
|
313
|
-
|
|
348
|
+
checkSuccess: (_request, result)=>{
|
|
349
|
+
const success = result && result.receipt && result.receipt.status === 'success' && result.receipt.logs.find((log)=>log.topics[0] === toEventSelector(getAbiItem({
|
|
350
|
+
abi: EmpireBaseAbi,
|
|
351
|
+
name: 'VoteCast'
|
|
352
|
+
})));
|
|
353
|
+
const logData = {
|
|
354
|
+
...result,
|
|
355
|
+
slotNumber,
|
|
356
|
+
round,
|
|
357
|
+
payload: payload.toString()
|
|
358
|
+
};
|
|
359
|
+
if (!success) {
|
|
360
|
+
this.log.error(`Voting in [${action}] for ${payload} at slot ${slotNumber} in round ${round} failed`, logData);
|
|
314
361
|
this.myLastVotes[voteType] = cachedLastVote;
|
|
362
|
+
return false;
|
|
315
363
|
} else {
|
|
316
|
-
this.log.info(`Voting in [${action}] for ${payload} at slot ${slotNumber} in round ${round}
|
|
364
|
+
this.log.info(`Voting in [${action}] for ${payload} at slot ${slotNumber} in round ${round} succeeded`, logData);
|
|
365
|
+
return true;
|
|
317
366
|
}
|
|
318
367
|
}
|
|
319
368
|
});
|
|
@@ -338,8 +387,10 @@ export class SequencerPublisher {
|
|
|
338
387
|
payload: slashPayload,
|
|
339
388
|
base: this.slashingProposerContract
|
|
340
389
|
};
|
|
390
|
+
} else {
|
|
391
|
+
const _ = voteType;
|
|
392
|
+
throw new Error('Unreachable: Invalid vote type');
|
|
341
393
|
}
|
|
342
|
-
throw new Error('Unreachable: Invalid vote type');
|
|
343
394
|
}
|
|
344
395
|
/**
|
|
345
396
|
* Enqueues a castVote transaction to cast a vote for a given slot number.
|
|
@@ -347,13 +398,13 @@ export class SequencerPublisher {
|
|
|
347
398
|
* @param timestamp - The timestamp of the slot to cast a vote for.
|
|
348
399
|
* @param voteType - The type of vote to cast.
|
|
349
400
|
* @returns True if the vote was successfully enqueued, false otherwise.
|
|
350
|
-
*/ async enqueueCastVote(slotNumber, timestamp, voteType) {
|
|
401
|
+
*/ async enqueueCastVote(slotNumber, timestamp, voteType, signerAddress, signer) {
|
|
351
402
|
const voteConfig = await this.getVoteConfig(slotNumber, voteType);
|
|
352
403
|
if (!voteConfig) {
|
|
353
404
|
return false;
|
|
354
405
|
}
|
|
355
406
|
const { payload, base } = voteConfig;
|
|
356
|
-
return this.enqueueCastVoteHelper(slotNumber, timestamp, voteType, payload, base);
|
|
407
|
+
return this.enqueueCastVoteHelper(slotNumber, timestamp, voteType, payload, base, signerAddress, signer);
|
|
357
408
|
}
|
|
358
409
|
/**
|
|
359
410
|
* Proposes a L2 block on L1.
|
|
@@ -524,12 +575,16 @@ export class SequencerPublisher {
|
|
|
524
575
|
blobs: encodedData.blobs.map((b)=>b.data),
|
|
525
576
|
kzg
|
|
526
577
|
},
|
|
527
|
-
|
|
578
|
+
checkSuccess: (request, result)=>{
|
|
528
579
|
if (!result) {
|
|
529
|
-
return;
|
|
580
|
+
return false;
|
|
530
581
|
}
|
|
531
582
|
const { receipt, stats, errorMsg } = result;
|
|
532
|
-
|
|
583
|
+
const success = receipt && receipt.status === 'success' && receipt.logs.find((log)=>log.topics[0] === toEventSelector(getAbiItem({
|
|
584
|
+
abi: RollupAbi,
|
|
585
|
+
name: 'L2BlockProposed'
|
|
586
|
+
})));
|
|
587
|
+
if (success) {
|
|
533
588
|
const endBlock = receipt.blockNumber;
|
|
534
589
|
const inclusionBlocks = Number(endBlock - startBlock);
|
|
535
590
|
const publishStats = {
|
|
@@ -544,7 +599,7 @@ export class SequencerPublisher {
|
|
|
544
599
|
blobCount: encodedData.blobs.length,
|
|
545
600
|
inclusionBlocks
|
|
546
601
|
};
|
|
547
|
-
this.log.
|
|
602
|
+
this.log.info(`Published L2 block to L1 rollup contract`, {
|
|
548
603
|
...stats,
|
|
549
604
|
...block.getStats(),
|
|
550
605
|
...receipt
|
|
@@ -557,11 +612,13 @@ export class SequencerPublisher {
|
|
|
557
612
|
return true;
|
|
558
613
|
} else {
|
|
559
614
|
this.metrics.recordFailedTx('process');
|
|
560
|
-
this.log.error(`Rollup process tx
|
|
615
|
+
this.log.error(`Rollup process tx failed. ${errorMsg ?? 'No error message'}`, undefined, {
|
|
561
616
|
...block.getStats(),
|
|
617
|
+
receipt,
|
|
562
618
|
txHash: receipt.transactionHash,
|
|
563
619
|
slotNumber: block.header.globalVariables.slotNumber.toBigInt()
|
|
564
620
|
});
|
|
621
|
+
return false;
|
|
565
622
|
}
|
|
566
623
|
}
|
|
567
624
|
});
|
|
@@ -38,7 +38,9 @@ export type SequencerEvents = {
|
|
|
38
38
|
reason: string;
|
|
39
39
|
}) => void;
|
|
40
40
|
['block-publish-failed']: (args: {
|
|
41
|
-
|
|
41
|
+
successfulActions?: Action[];
|
|
42
|
+
failedActions?: Action[];
|
|
43
|
+
sentActions?: Action[];
|
|
42
44
|
expiredActions?: Action[];
|
|
43
45
|
}) => void;
|
|
44
46
|
['block-published']: (args: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequencer.d.ts","sourceRoot":"","sources":["../../src/sequencer/sequencer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"sequencer.d.ts","sourceRoot":"","sources":["../../src/sequencer/sequencer.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
6
6
|
}
|
|
7
7
|
import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
8
8
|
import { FormattedViemError, NoCommitteeError } from '@aztec/ethereum';
|
|
9
|
+
import { Buffer32 } from '@aztec/foundation/buffer';
|
|
9
10
|
import { omit } from '@aztec/foundation/collection';
|
|
10
11
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
11
12
|
import { Fr } from '@aztec/foundation/fields';
|
|
@@ -294,8 +295,8 @@ export { SequencerState };
|
|
|
294
295
|
validatorAddresses
|
|
295
296
|
});
|
|
296
297
|
const newGlobalVariables = await this.globalsBuilder.buildGlobalVariables(newBlockNumber, this.coinbase, this._feeRecipient, slot);
|
|
297
|
-
const enqueueGovernanceVotePromise = this.publisher.enqueueCastVote(slot, newGlobalVariables.timestamp, VoteType.GOVERNANCE);
|
|
298
|
-
const enqueueSlashingVotePromise = this.publisher.enqueueCastVote(slot, newGlobalVariables.timestamp, VoteType.SLASHING);
|
|
298
|
+
const enqueueGovernanceVotePromise = this.publisher.enqueueCastVote(slot, newGlobalVariables.timestamp, VoteType.GOVERNANCE, proposerAddress, (msg)=>this.validatorClient.signWithAddress(proposerAddress, Buffer32.fromString(msg)).then((s)=>s.toString()));
|
|
299
|
+
const enqueueSlashingVotePromise = this.publisher.enqueueCastVote(slot, newGlobalVariables.timestamp, VoteType.SLASHING, proposerAddress, (msg)=>this.validatorClient.signWithAddress(proposerAddress, Buffer32.fromString(msg)).then((s)=>s.toString()));
|
|
299
300
|
this.setState(SequencerState.INITIALIZING_PROPOSAL, slot);
|
|
300
301
|
this.log.verbose(`Preparing proposal for block ${newBlockNumber} at slot ${slot}`, {
|
|
301
302
|
proposer: proposerInNextSlot?.toString(),
|
|
@@ -360,7 +361,7 @@ export { SequencerState };
|
|
|
360
361
|
});
|
|
361
362
|
});
|
|
362
363
|
const l1Response = await this.publisher.sendRequests();
|
|
363
|
-
const proposedBlock = l1Response?.
|
|
364
|
+
const proposedBlock = l1Response?.successfulActions.find((a)=>a === 'propose');
|
|
364
365
|
if (proposedBlock) {
|
|
365
366
|
this.lastBlockPublished = block;
|
|
366
367
|
this.emit('block-published', {
|
|
@@ -372,10 +373,7 @@ export { SequencerState };
|
|
|
372
373
|
this.isFlushing = false;
|
|
373
374
|
}
|
|
374
375
|
} else if (block) {
|
|
375
|
-
this.emit('block-publish-failed', {
|
|
376
|
-
validActions: l1Response?.validActions,
|
|
377
|
-
expiredActions: l1Response?.expiredActions
|
|
378
|
-
});
|
|
376
|
+
this.emit('block-publish-failed', l1Response ?? {});
|
|
379
377
|
}
|
|
380
378
|
this.setState(SequencerState.IDLE, undefined);
|
|
381
379
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/sequencer-client",
|
|
3
|
-
"version": "1.0.0-nightly.
|
|
3
|
+
"version": "1.0.0-nightly.20250710",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -26,37 +26,37 @@
|
|
|
26
26
|
"test:integration:run": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --config jest.integration.config.json"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@aztec/aztec.js": "1.0.0-nightly.
|
|
30
|
-
"@aztec/bb-prover": "1.0.0-nightly.
|
|
31
|
-
"@aztec/blob-lib": "1.0.0-nightly.
|
|
32
|
-
"@aztec/blob-sink": "1.0.0-nightly.
|
|
33
|
-
"@aztec/constants": "1.0.0-nightly.
|
|
34
|
-
"@aztec/epoch-cache": "1.0.0-nightly.
|
|
35
|
-
"@aztec/ethereum": "1.0.0-nightly.
|
|
36
|
-
"@aztec/foundation": "1.0.0-nightly.
|
|
37
|
-
"@aztec/l1-artifacts": "1.0.0-nightly.
|
|
38
|
-
"@aztec/merkle-tree": "1.0.0-nightly.
|
|
39
|
-
"@aztec/noir-acvm_js": "1.0.0-nightly.
|
|
40
|
-
"@aztec/noir-contracts.js": "1.0.0-nightly.
|
|
41
|
-
"@aztec/noir-protocol-circuits-types": "1.0.0-nightly.
|
|
42
|
-
"@aztec/noir-types": "1.0.0-nightly.
|
|
43
|
-
"@aztec/p2p": "1.0.0-nightly.
|
|
44
|
-
"@aztec/protocol-contracts": "1.0.0-nightly.
|
|
45
|
-
"@aztec/prover-client": "1.0.0-nightly.
|
|
46
|
-
"@aztec/simulator": "1.0.0-nightly.
|
|
47
|
-
"@aztec/slasher": "1.0.0-nightly.
|
|
48
|
-
"@aztec/stdlib": "1.0.0-nightly.
|
|
49
|
-
"@aztec/telemetry-client": "1.0.0-nightly.
|
|
50
|
-
"@aztec/validator-client": "1.0.0-nightly.
|
|
51
|
-
"@aztec/world-state": "1.0.0-nightly.
|
|
29
|
+
"@aztec/aztec.js": "1.0.0-nightly.20250710",
|
|
30
|
+
"@aztec/bb-prover": "1.0.0-nightly.20250710",
|
|
31
|
+
"@aztec/blob-lib": "1.0.0-nightly.20250710",
|
|
32
|
+
"@aztec/blob-sink": "1.0.0-nightly.20250710",
|
|
33
|
+
"@aztec/constants": "1.0.0-nightly.20250710",
|
|
34
|
+
"@aztec/epoch-cache": "1.0.0-nightly.20250710",
|
|
35
|
+
"@aztec/ethereum": "1.0.0-nightly.20250710",
|
|
36
|
+
"@aztec/foundation": "1.0.0-nightly.20250710",
|
|
37
|
+
"@aztec/l1-artifacts": "1.0.0-nightly.20250710",
|
|
38
|
+
"@aztec/merkle-tree": "1.0.0-nightly.20250710",
|
|
39
|
+
"@aztec/noir-acvm_js": "1.0.0-nightly.20250710",
|
|
40
|
+
"@aztec/noir-contracts.js": "1.0.0-nightly.20250710",
|
|
41
|
+
"@aztec/noir-protocol-circuits-types": "1.0.0-nightly.20250710",
|
|
42
|
+
"@aztec/noir-types": "1.0.0-nightly.20250710",
|
|
43
|
+
"@aztec/p2p": "1.0.0-nightly.20250710",
|
|
44
|
+
"@aztec/protocol-contracts": "1.0.0-nightly.20250710",
|
|
45
|
+
"@aztec/prover-client": "1.0.0-nightly.20250710",
|
|
46
|
+
"@aztec/simulator": "1.0.0-nightly.20250710",
|
|
47
|
+
"@aztec/slasher": "1.0.0-nightly.20250710",
|
|
48
|
+
"@aztec/stdlib": "1.0.0-nightly.20250710",
|
|
49
|
+
"@aztec/telemetry-client": "1.0.0-nightly.20250710",
|
|
50
|
+
"@aztec/validator-client": "1.0.0-nightly.20250710",
|
|
51
|
+
"@aztec/world-state": "1.0.0-nightly.20250710",
|
|
52
52
|
"lodash.chunk": "^4.2.0",
|
|
53
53
|
"lodash.pick": "^4.4.0",
|
|
54
54
|
"tslib": "^2.4.0",
|
|
55
55
|
"viem": "2.23.7"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@aztec/archiver": "1.0.0-nightly.
|
|
59
|
-
"@aztec/kv-store": "1.0.0-nightly.
|
|
58
|
+
"@aztec/archiver": "1.0.0-nightly.20250710",
|
|
59
|
+
"@aztec/kv-store": "1.0.0-nightly.20250710",
|
|
60
60
|
"@jest/globals": "^30.0.0",
|
|
61
61
|
"@types/jest": "^30.0.0",
|
|
62
62
|
"@types/lodash.chunk": "^4.2.7",
|
package/src/publisher/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { SequencerPublisher } from './sequencer-publisher.js';
|
|
1
|
+
export { SequencerPublisher, VoteType } from './sequencer-publisher.js';
|
|
@@ -27,7 +27,7 @@ import { toHex as toPaddedHex } from '@aztec/foundation/bigint-buffer';
|
|
|
27
27
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
28
28
|
import { createLogger } from '@aztec/foundation/log';
|
|
29
29
|
import { DateProvider, Timer } from '@aztec/foundation/timer';
|
|
30
|
-
import { RollupAbi } from '@aztec/l1-artifacts';
|
|
30
|
+
import { EmpireBaseAbi, ErrorsAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
31
31
|
import { CommitteeAttestation } from '@aztec/stdlib/block';
|
|
32
32
|
import { ConsensusPayload, SignatureDomainSeparator, getHashedSignaturePayload } from '@aztec/stdlib/p2p';
|
|
33
33
|
import type { L1PublishBlockStats } from '@aztec/stdlib/stats';
|
|
@@ -35,7 +35,7 @@ import { type ProposedBlockHeader, StateReference, TxHash } from '@aztec/stdlib/
|
|
|
35
35
|
import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
36
36
|
|
|
37
37
|
import pick from 'lodash.pick';
|
|
38
|
-
import { type TransactionReceipt, encodeFunctionData, toHex } from 'viem';
|
|
38
|
+
import { type TransactionReceipt, encodeFunctionData, getAbiItem, toEventSelector, toHex } from 'viem';
|
|
39
39
|
|
|
40
40
|
import type { PublisherConfig, TxSenderConfig } from './config.js';
|
|
41
41
|
import { SequencerPublisherMetrics } from './sequencer-publisher-metrics.js';
|
|
@@ -71,10 +71,10 @@ interface RequestWithExpiry {
|
|
|
71
71
|
lastValidL2Slot: bigint;
|
|
72
72
|
gasConfig?: Pick<L1GasConfig, 'txTimeoutAt' | 'gasLimit'>;
|
|
73
73
|
blobConfig?: L1BlobInputs;
|
|
74
|
-
|
|
74
|
+
checkSuccess: (
|
|
75
75
|
request: L1TxRequest,
|
|
76
76
|
result?: { receipt: TransactionReceipt; gasPrice: GasPrice; stats?: TransactionStats; errorMsg?: string },
|
|
77
|
-
) =>
|
|
77
|
+
) => boolean;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
export class SequencerPublisher {
|
|
@@ -119,7 +119,7 @@ export class SequencerPublisher {
|
|
|
119
119
|
protected requests: RequestWithExpiry[] = [];
|
|
120
120
|
|
|
121
121
|
constructor(
|
|
122
|
-
config: TxSenderConfig & PublisherConfig & Pick<L1ContractsConfig, 'ethereumSlotDuration'>,
|
|
122
|
+
private config: TxSenderConfig & PublisherConfig & Pick<L1ContractsConfig, 'ethereumSlotDuration'>,
|
|
123
123
|
deps: {
|
|
124
124
|
telemetry?: TelemetryClient;
|
|
125
125
|
blobSinkClient?: BlobSinkClientInterface;
|
|
@@ -235,9 +235,7 @@ export class SequencerPublisher {
|
|
|
235
235
|
const gasConfig: RequestWithExpiry['gasConfig'] = { gasLimit, txTimeoutAt };
|
|
236
236
|
|
|
237
237
|
try {
|
|
238
|
-
this.log.debug('Forwarding transactions', {
|
|
239
|
-
validRequests: validRequests.map(request => request.action),
|
|
240
|
-
});
|
|
238
|
+
this.log.debug('Forwarding transactions', { validRequests: validRequests.map(request => request.action) });
|
|
241
239
|
const result = await Multicall3.forward(
|
|
242
240
|
validRequests.map(request => request.request),
|
|
243
241
|
this.l1TxUtils,
|
|
@@ -246,8 +244,8 @@ export class SequencerPublisher {
|
|
|
246
244
|
this.rollupContract.address,
|
|
247
245
|
this.log,
|
|
248
246
|
);
|
|
249
|
-
this.callbackBundledTransactions(validRequests, result);
|
|
250
|
-
return { result, expiredActions, validActions };
|
|
247
|
+
const { successfulActions = [], failedActions = [] } = this.callbackBundledTransactions(validRequests, result);
|
|
248
|
+
return { result, expiredActions, sentActions: validActions, successfulActions, failedActions };
|
|
251
249
|
} catch (err) {
|
|
252
250
|
const viemError = formatViemError(err);
|
|
253
251
|
this.log.error(`Failed to publish bundled transactions`, viemError);
|
|
@@ -265,17 +263,22 @@ export class SequencerPublisher {
|
|
|
265
263
|
requests: RequestWithExpiry[],
|
|
266
264
|
result?: { receipt: TransactionReceipt; gasPrice: GasPrice } | FormattedViemError,
|
|
267
265
|
) {
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
266
|
+
const actionsListStr = requests.map(r => r.action).join(', ');
|
|
267
|
+
if (result instanceof FormattedViemError) {
|
|
268
|
+
this.log.error(`Failed to publish bundled transactions (${actionsListStr})`, result);
|
|
269
|
+
return { failedActions: requests.map(r => r.action) };
|
|
270
|
+
} else {
|
|
271
|
+
this.log.verbose(`Published bundled transactions (${actionsListStr})`, { result, requests });
|
|
272
|
+
const successfulActions: Action[] = [];
|
|
273
|
+
const failedActions: Action[] = [];
|
|
274
|
+
for (const request of requests) {
|
|
275
|
+
if (request.checkSuccess(request.request, result)) {
|
|
276
|
+
successfulActions.push(request.action);
|
|
277
|
+
} else {
|
|
278
|
+
failedActions.push(request.action);
|
|
279
|
+
}
|
|
275
280
|
}
|
|
276
|
-
|
|
277
|
-
if (isError) {
|
|
278
|
-
this.log.error('Failed to publish bundled transactions', result);
|
|
281
|
+
return { successfulActions, failedActions };
|
|
279
282
|
}
|
|
280
283
|
}
|
|
281
284
|
|
|
@@ -406,6 +409,8 @@ export class SequencerPublisher {
|
|
|
406
409
|
voteType: VoteType,
|
|
407
410
|
payload: EthAddress,
|
|
408
411
|
base: IEmpireBase,
|
|
412
|
+
signerAddress: EthAddress,
|
|
413
|
+
signer: (msg: `0x${string}`) => Promise<`0x${string}`>,
|
|
409
414
|
): Promise<boolean> {
|
|
410
415
|
if (this.myLastVotes[voteType] >= slotNumber) {
|
|
411
416
|
return false;
|
|
@@ -425,7 +430,12 @@ export class SequencerPublisher {
|
|
|
425
430
|
|
|
426
431
|
const action = voteType === VoteType.GOVERNANCE ? 'governance-vote' : 'slashing-vote';
|
|
427
432
|
|
|
428
|
-
const request = await base.createVoteRequestWithSignature(
|
|
433
|
+
const request = await base.createVoteRequestWithSignature(
|
|
434
|
+
payload.toString(),
|
|
435
|
+
this.config.l1ChainId,
|
|
436
|
+
signerAddress.toString(),
|
|
437
|
+
signer,
|
|
438
|
+
);
|
|
429
439
|
this.log.debug(`Created ${action} request with signature`, {
|
|
430
440
|
request,
|
|
431
441
|
round,
|
|
@@ -433,16 +443,42 @@ export class SequencerPublisher {
|
|
|
433
443
|
lastValidL2Slot: slotNumber,
|
|
434
444
|
});
|
|
435
445
|
|
|
446
|
+
try {
|
|
447
|
+
await this.l1TxUtils.simulate(request, { time: timestamp }, [], ErrorsAbi);
|
|
448
|
+
this.log.debug(`Simulation for ${action} at slot ${slotNumber} succeeded`, { request });
|
|
449
|
+
} catch (err) {
|
|
450
|
+
this.log.warn(`Failed simulation for ${action} at slot ${slotNumber} (enqueuing the action anyway)`, err);
|
|
451
|
+
// Yes, we enqueue the request anyway, in case there was a bug with the simulation itself
|
|
452
|
+
}
|
|
453
|
+
|
|
436
454
|
this.addRequest({
|
|
437
455
|
gasConfig: { gasLimit: SequencerPublisher.VOTE_GAS_GUESS },
|
|
438
456
|
action,
|
|
439
457
|
request,
|
|
440
458
|
lastValidL2Slot: slotNumber,
|
|
441
|
-
|
|
442
|
-
|
|
459
|
+
checkSuccess: (_request, result) => {
|
|
460
|
+
const success =
|
|
461
|
+
result &&
|
|
462
|
+
result.receipt &&
|
|
463
|
+
result.receipt.status === 'success' &&
|
|
464
|
+
result.receipt.logs.find(
|
|
465
|
+
log => log.topics[0] === toEventSelector(getAbiItem({ abi: EmpireBaseAbi, name: 'VoteCast' })),
|
|
466
|
+
);
|
|
467
|
+
|
|
468
|
+
const logData = { ...result, slotNumber, round, payload: payload.toString() };
|
|
469
|
+
if (!success) {
|
|
470
|
+
this.log.error(
|
|
471
|
+
`Voting in [${action}] for ${payload} at slot ${slotNumber} in round ${round} failed`,
|
|
472
|
+
logData,
|
|
473
|
+
);
|
|
443
474
|
this.myLastVotes[voteType] = cachedLastVote;
|
|
475
|
+
return false;
|
|
444
476
|
} else {
|
|
445
|
-
this.log.info(
|
|
477
|
+
this.log.info(
|
|
478
|
+
`Voting in [${action}] for ${payload} at slot ${slotNumber} in round ${round} succeeded`,
|
|
479
|
+
logData,
|
|
480
|
+
);
|
|
481
|
+
return true;
|
|
446
482
|
}
|
|
447
483
|
},
|
|
448
484
|
});
|
|
@@ -465,8 +501,10 @@ export class SequencerPublisher {
|
|
|
465
501
|
}
|
|
466
502
|
this.log.info(`Slash payload: ${slashPayload}`);
|
|
467
503
|
return { payload: slashPayload, base: this.slashingProposerContract };
|
|
504
|
+
} else {
|
|
505
|
+
const _: never = voteType;
|
|
506
|
+
throw new Error('Unreachable: Invalid vote type');
|
|
468
507
|
}
|
|
469
|
-
throw new Error('Unreachable: Invalid vote type');
|
|
470
508
|
}
|
|
471
509
|
|
|
472
510
|
/**
|
|
@@ -476,13 +514,19 @@ export class SequencerPublisher {
|
|
|
476
514
|
* @param voteType - The type of vote to cast.
|
|
477
515
|
* @returns True if the vote was successfully enqueued, false otherwise.
|
|
478
516
|
*/
|
|
479
|
-
public async enqueueCastVote(
|
|
517
|
+
public async enqueueCastVote(
|
|
518
|
+
slotNumber: bigint,
|
|
519
|
+
timestamp: bigint,
|
|
520
|
+
voteType: VoteType,
|
|
521
|
+
signerAddress: EthAddress,
|
|
522
|
+
signer: (msg: `0x${string}`) => Promise<`0x${string}`>,
|
|
523
|
+
): Promise<boolean> {
|
|
480
524
|
const voteConfig = await this.getVoteConfig(slotNumber, voteType);
|
|
481
525
|
if (!voteConfig) {
|
|
482
526
|
return false;
|
|
483
527
|
}
|
|
484
528
|
const { payload, base } = voteConfig;
|
|
485
|
-
return this.enqueueCastVoteHelper(slotNumber, timestamp, voteType, payload, base);
|
|
529
|
+
return this.enqueueCastVoteHelper(slotNumber, timestamp, voteType, payload, base, signerAddress, signer);
|
|
486
530
|
}
|
|
487
531
|
|
|
488
532
|
/**
|
|
@@ -701,12 +745,18 @@ export class SequencerPublisher {
|
|
|
701
745
|
blobs: encodedData.blobs.map(b => b.data),
|
|
702
746
|
kzg,
|
|
703
747
|
},
|
|
704
|
-
|
|
748
|
+
checkSuccess: (request, result) => {
|
|
705
749
|
if (!result) {
|
|
706
|
-
return;
|
|
750
|
+
return false;
|
|
707
751
|
}
|
|
708
752
|
const { receipt, stats, errorMsg } = result;
|
|
709
|
-
|
|
753
|
+
const success =
|
|
754
|
+
receipt &&
|
|
755
|
+
receipt.status === 'success' &&
|
|
756
|
+
receipt.logs.find(
|
|
757
|
+
log => log.topics[0] === toEventSelector(getAbiItem({ abi: RollupAbi, name: 'L2BlockProposed' })),
|
|
758
|
+
);
|
|
759
|
+
if (success) {
|
|
710
760
|
const endBlock = receipt.blockNumber;
|
|
711
761
|
const inclusionBlocks = Number(endBlock - startBlock);
|
|
712
762
|
const publishStats: L1PublishBlockStats = {
|
|
@@ -721,23 +771,23 @@ export class SequencerPublisher {
|
|
|
721
771
|
blobCount: encodedData.blobs.length,
|
|
722
772
|
inclusionBlocks,
|
|
723
773
|
};
|
|
724
|
-
this.log.
|
|
774
|
+
this.log.info(`Published L2 block to L1 rollup contract`, { ...stats, ...block.getStats(), ...receipt });
|
|
725
775
|
this.metrics.recordProcessBlockTx(timer.ms(), publishStats);
|
|
726
776
|
|
|
727
777
|
// Send the blobs to the blob sink
|
|
728
778
|
this.sendBlobsToBlobSink(receipt.blockHash, encodedData.blobs).catch(_err => {
|
|
729
779
|
this.log.error('Failed to send blobs to blob sink');
|
|
730
780
|
});
|
|
731
|
-
|
|
732
781
|
return true;
|
|
733
782
|
} else {
|
|
734
783
|
this.metrics.recordFailedTx('process');
|
|
735
|
-
|
|
736
|
-
this.log.error(`Rollup process tx reverted. ${errorMsg ?? 'No error message'}`, undefined, {
|
|
784
|
+
this.log.error(`Rollup process tx failed. ${errorMsg ?? 'No error message'}`, undefined, {
|
|
737
785
|
...block.getStats(),
|
|
786
|
+
receipt,
|
|
738
787
|
txHash: receipt.transactionHash,
|
|
739
788
|
slotNumber: block.header.globalVariables.slotNumber.toBigInt(),
|
|
740
789
|
});
|
|
790
|
+
return false;
|
|
741
791
|
}
|
|
742
792
|
},
|
|
743
793
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { L2Block } from '@aztec/aztec.js';
|
|
2
2
|
import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
3
3
|
import { FormattedViemError, NoCommitteeError, type ViemPublicClient } from '@aztec/ethereum';
|
|
4
|
+
import { Buffer32 } from '@aztec/foundation/buffer';
|
|
4
5
|
import { omit } from '@aztec/foundation/collection';
|
|
5
6
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
6
7
|
import { Fr } from '@aztec/foundation/fields';
|
|
@@ -67,7 +68,12 @@ export type SequencerEvents = {
|
|
|
67
68
|
['proposer-rollup-check-failed']: (args: { reason: string }) => void;
|
|
68
69
|
['tx-count-check-failed']: (args: { minTxs: number; availableTxs: number }) => void;
|
|
69
70
|
['block-build-failed']: (args: { reason: string }) => void;
|
|
70
|
-
['block-publish-failed']: (args: {
|
|
71
|
+
['block-publish-failed']: (args: {
|
|
72
|
+
successfulActions?: Action[];
|
|
73
|
+
failedActions?: Action[];
|
|
74
|
+
sentActions?: Action[];
|
|
75
|
+
expiredActions?: Action[];
|
|
76
|
+
}) => void;
|
|
71
77
|
['block-published']: (args: { blockNumber: number; slot: number }) => void;
|
|
72
78
|
};
|
|
73
79
|
|
|
@@ -355,6 +361,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
355
361
|
// Double check we are good for proposing at the next block before we start operations.
|
|
356
362
|
// We should never fail this check assuming the logic above is good.
|
|
357
363
|
const proposerAddress = proposerInNextSlot ?? EthAddress.ZERO;
|
|
364
|
+
|
|
358
365
|
const canProposeCheck = await this.publisher.canProposeAtNextEthBlock(chainTipArchive.toBuffer(), proposerAddress);
|
|
359
366
|
if (canProposeCheck === undefined) {
|
|
360
367
|
this.log.warn(
|
|
@@ -380,7 +387,9 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
380
387
|
}
|
|
381
388
|
|
|
382
389
|
this.log.debug(
|
|
383
|
-
`${
|
|
390
|
+
`${
|
|
391
|
+
proposerInNextSlot ? `Validator ${proposerInNextSlot.toString()} can` : 'Can'
|
|
392
|
+
} propose block ${newBlockNumber} at slot ${slot}`,
|
|
384
393
|
{ ...syncLogData, validatorAddresses },
|
|
385
394
|
);
|
|
386
395
|
|
|
@@ -395,12 +404,16 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
395
404
|
slot,
|
|
396
405
|
newGlobalVariables.timestamp,
|
|
397
406
|
VoteType.GOVERNANCE,
|
|
407
|
+
proposerAddress,
|
|
408
|
+
msg => this.validatorClient!.signWithAddress(proposerAddress, Buffer32.fromString(msg)).then(s => s.toString()),
|
|
398
409
|
);
|
|
399
410
|
|
|
400
411
|
const enqueueSlashingVotePromise = this.publisher.enqueueCastVote(
|
|
401
412
|
slot,
|
|
402
413
|
newGlobalVariables.timestamp,
|
|
403
414
|
VoteType.SLASHING,
|
|
415
|
+
proposerAddress,
|
|
416
|
+
msg => this.validatorClient!.signWithAddress(proposerAddress, Buffer32.fromString(msg)).then(s => s.toString()),
|
|
404
417
|
);
|
|
405
418
|
|
|
406
419
|
this.setState(SequencerState.INITIALIZING_PROPOSAL, slot);
|
|
@@ -462,7 +475,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
462
475
|
});
|
|
463
476
|
|
|
464
477
|
const l1Response = await this.publisher.sendRequests();
|
|
465
|
-
const proposedBlock = l1Response?.
|
|
478
|
+
const proposedBlock = l1Response?.successfulActions.find(a => a === 'propose');
|
|
466
479
|
if (proposedBlock) {
|
|
467
480
|
this.lastBlockPublished = block;
|
|
468
481
|
this.emit('block-published', { blockNumber: newBlockNumber, slot: Number(slot) });
|
|
@@ -471,10 +484,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
471
484
|
this.isFlushing = false;
|
|
472
485
|
}
|
|
473
486
|
} else if (block) {
|
|
474
|
-
this.emit('block-publish-failed', {
|
|
475
|
-
validActions: l1Response?.validActions,
|
|
476
|
-
expiredActions: l1Response?.expiredActions,
|
|
477
|
-
});
|
|
487
|
+
this.emit('block-publish-failed', l1Response ?? {});
|
|
478
488
|
}
|
|
479
489
|
|
|
480
490
|
this.setState(SequencerState.IDLE, undefined);
|