@aztec/sequencer-client 0.55.1 → 0.56.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/block_builder/index.d.ts +4 -23
- package/dest/block_builder/index.d.ts.map +1 -1
- package/dest/block_builder/index.js +3 -40
- package/dest/block_builder/light.d.ts +30 -0
- package/dest/block_builder/light.d.ts.map +1 -0
- package/dest/block_builder/light.js +65 -0
- package/dest/block_builder/orchestrator.d.ts +26 -0
- package/dest/block_builder/orchestrator.d.ts.map +1 -0
- package/dest/block_builder/orchestrator.js +40 -0
- package/dest/client/sequencer-client.d.ts +2 -1
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +3 -3
- package/dest/publisher/l1-publisher.d.ts +2 -1
- package/dest/publisher/l1-publisher.d.ts.map +1 -1
- package/dest/publisher/l1-publisher.js +5 -4
- package/dest/sequencer/sequencer.d.ts +5 -2
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +10 -7
- package/dest/tx_validator/gas_validator.d.ts +1 -0
- package/dest/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/tx_validator/gas_validator.js +7 -4
- package/dest/tx_validator/phases_validator.d.ts +1 -0
- package/dest/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/tx_validator/phases_validator.js +20 -20
- package/dest/tx_validator/test_utils.js +4 -4
- package/dest/tx_validator/tx_validator_factory.d.ts.map +1 -1
- package/dest/tx_validator/tx_validator_factory.js +5 -4
- package/package.json +19 -19
- package/src/block_builder/index.ts +5 -49
- package/src/block_builder/light.ts +111 -0
- package/src/block_builder/orchestrator.ts +51 -0
- package/src/client/sequencer-client.ts +4 -3
- package/src/publisher/l1-publisher.ts +6 -4
- package/src/sequencer/sequencer.ts +7 -7
- package/src/tx_validator/gas_validator.ts +7 -3
- package/src/tx_validator/phases_validator.ts +5 -6
- package/src/tx_validator/test_utils.ts +3 -3
- package/src/tx_validator/tx_validator_factory.ts +5 -4
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { TestCircuitProver } from '@aztec/bb-prover';
|
|
2
|
+
import {
|
|
3
|
+
type BlockSimulator,
|
|
4
|
+
type MerkleTreeOperations,
|
|
5
|
+
type ProcessedTx,
|
|
6
|
+
type ProvingTicket,
|
|
7
|
+
type SimulationBlockResult,
|
|
8
|
+
} from '@aztec/circuit-types';
|
|
9
|
+
import { type Fr, type GlobalVariables } from '@aztec/circuits.js';
|
|
10
|
+
import { ProvingOrchestrator } from '@aztec/prover-client/orchestrator';
|
|
11
|
+
import { type SimulationProvider } from '@aztec/simulator';
|
|
12
|
+
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
13
|
+
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Implements a block simulator using a test circuit prover under the hood, which just simulates circuits and outputs empty proofs.
|
|
17
|
+
* This class is temporary and should die once we switch from tx effects to tx objects submissions, since sequencers won't have
|
|
18
|
+
* the need to create L2 block headers to submit to L1. When we do that, we should also remove the references to the
|
|
19
|
+
* prover-client and bb-prover packages from this package.
|
|
20
|
+
*/
|
|
21
|
+
export class OrchestratorBlockBuilder implements BlockSimulator {
|
|
22
|
+
private orchestrator: ProvingOrchestrator;
|
|
23
|
+
constructor(db: MerkleTreeOperations, simulationProvider: SimulationProvider, telemetry: TelemetryClient) {
|
|
24
|
+
const testProver = new TestCircuitProver(telemetry, simulationProvider);
|
|
25
|
+
this.orchestrator = new ProvingOrchestrator(db, testProver, telemetry);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
startNewBlock(numTxs: number, globalVariables: GlobalVariables, l1ToL2Messages: Fr[]): Promise<ProvingTicket> {
|
|
29
|
+
return this.orchestrator.startNewBlock(numTxs, globalVariables, l1ToL2Messages);
|
|
30
|
+
}
|
|
31
|
+
cancel(): void {
|
|
32
|
+
this.orchestrator.cancel();
|
|
33
|
+
}
|
|
34
|
+
finaliseBlock(): Promise<SimulationBlockResult> {
|
|
35
|
+
return this.orchestrator.finaliseBlock();
|
|
36
|
+
}
|
|
37
|
+
setBlockCompleted(): Promise<void> {
|
|
38
|
+
return this.orchestrator.setBlockCompleted();
|
|
39
|
+
}
|
|
40
|
+
addNewTx(tx: ProcessedTx): Promise<void> {
|
|
41
|
+
return this.orchestrator.addNewTx(tx);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export class OrchestratorBlockBuilderFactory {
|
|
46
|
+
constructor(private simulationProvider: SimulationProvider, private telemetry?: TelemetryClient) {}
|
|
47
|
+
|
|
48
|
+
create(db: MerkleTreeOperations): BlockSimulator {
|
|
49
|
+
return new OrchestratorBlockBuilder(db, this.simulationProvider, this.telemetry ?? new NoopTelemetryClient());
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { type L1ToL2MessageSource, type L2BlockSource, type WorldStateSynchronizer } from '@aztec/circuit-types';
|
|
2
|
+
import { type EthAddress } from '@aztec/foundation/eth-address';
|
|
2
3
|
import { type P2P } from '@aztec/p2p';
|
|
3
4
|
import { PublicProcessorFactory, type SimulationProvider } from '@aztec/simulator';
|
|
4
5
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
5
6
|
import { type ContractDataSource } from '@aztec/types/contracts';
|
|
6
7
|
import { type ValidatorClient } from '@aztec/validator-client';
|
|
7
8
|
|
|
8
|
-
import {
|
|
9
|
+
import { LightweightBlockBuilderFactory } from '../block_builder/index.js';
|
|
9
10
|
import { type SequencerClientConfig } from '../config.js';
|
|
10
11
|
import { GlobalVariableBuilder } from '../global_variable_builder/index.js';
|
|
11
12
|
import { L1Publisher } from '../publisher/index.js';
|
|
@@ -59,7 +60,7 @@ export class SequencerClient {
|
|
|
59
60
|
globalsBuilder,
|
|
60
61
|
p2pClient,
|
|
61
62
|
worldStateSynchronizer,
|
|
62
|
-
new
|
|
63
|
+
new LightweightBlockBuilderFactory(telemetryClient),
|
|
63
64
|
l2BlockSource,
|
|
64
65
|
l1ToL2MessageSource,
|
|
65
66
|
publicProcessorFactory,
|
|
@@ -99,7 +100,7 @@ export class SequencerClient {
|
|
|
99
100
|
this.sequencer.restart();
|
|
100
101
|
}
|
|
101
102
|
|
|
102
|
-
get coinbase() {
|
|
103
|
+
get coinbase(): EthAddress {
|
|
103
104
|
return this.sequencer.coinbase;
|
|
104
105
|
}
|
|
105
106
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { type L2Block, type
|
|
2
|
-
import { getHashedSignaturePayload } from '@aztec/circuit-types';
|
|
1
|
+
import { ConsensusPayload, type L2Block, type TxHash, getHashedSignaturePayload } from '@aztec/circuit-types';
|
|
3
2
|
import { type L1PublishBlockStats, type L1PublishProofStats } from '@aztec/circuit-types/stats';
|
|
4
3
|
import { ETHEREUM_SLOT_DURATION, EthAddress, type Header, type Proof } from '@aztec/circuits.js';
|
|
5
4
|
import { createEthereumChain } from '@aztec/ethereum';
|
|
5
|
+
import { type Signature } from '@aztec/foundation/eth-signature';
|
|
6
6
|
import { type Fr } from '@aztec/foundation/fields';
|
|
7
7
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
8
8
|
import { serializeToBuffer } from '@aztec/foundation/serialize';
|
|
@@ -236,7 +236,9 @@ export class L1Publisher {
|
|
|
236
236
|
blockHash: block.hash().toString(),
|
|
237
237
|
};
|
|
238
238
|
|
|
239
|
-
const
|
|
239
|
+
const consensusPayload = new ConsensusPayload(block.header, block.archive.root, txHashes ?? []);
|
|
240
|
+
|
|
241
|
+
const digest = getHashedSignaturePayload(consensusPayload);
|
|
240
242
|
const proposeTxArgs = {
|
|
241
243
|
header: block.header.toBuffer(),
|
|
242
244
|
archive: block.archive.root.toBuffer(),
|
|
@@ -255,7 +257,7 @@ export class L1Publisher {
|
|
|
255
257
|
// By simulation issue, I mean the fact that the block.timestamp is equal to the last block, not the next, which
|
|
256
258
|
// make time consistency checks break.
|
|
257
259
|
await this.validateBlockForSubmission(block.header, {
|
|
258
|
-
digest,
|
|
260
|
+
digest: digest.toBuffer(),
|
|
259
261
|
signatures: attestations ?? [],
|
|
260
262
|
});
|
|
261
263
|
|
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
type L2Block,
|
|
5
5
|
type L2BlockSource,
|
|
6
6
|
type ProcessedTx,
|
|
7
|
-
Signature,
|
|
8
7
|
Tx,
|
|
9
8
|
type TxHash,
|
|
10
9
|
type TxValidator,
|
|
@@ -15,13 +14,14 @@ import { type AllowedElement, BlockProofError, PROVING_STATUS } from '@aztec/cir
|
|
|
15
14
|
import { type L2BlockBuiltStats } from '@aztec/circuit-types/stats';
|
|
16
15
|
import {
|
|
17
16
|
AppendOnlyTreeSnapshot,
|
|
18
|
-
AztecAddress,
|
|
19
17
|
ContentCommitment,
|
|
20
|
-
EthAddress,
|
|
21
18
|
GENESIS_ARCHIVE_ROOT,
|
|
22
19
|
Header,
|
|
23
20
|
StateReference,
|
|
24
21
|
} from '@aztec/circuits.js';
|
|
22
|
+
import { AztecAddress } from '@aztec/foundation/aztec-address';
|
|
23
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
24
|
+
import { Signature } from '@aztec/foundation/eth-signature';
|
|
25
25
|
import { Fr } from '@aztec/foundation/fields';
|
|
26
26
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
27
27
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
@@ -443,7 +443,7 @@ export class Sequencer {
|
|
|
443
443
|
processedTxsCount: processedTxs.length,
|
|
444
444
|
})
|
|
445
445
|
) {
|
|
446
|
-
blockBuilder.
|
|
446
|
+
blockBuilder.cancel();
|
|
447
447
|
throw new Error('Should not propose the block');
|
|
448
448
|
}
|
|
449
449
|
|
|
@@ -537,7 +537,7 @@ export class Sequencer {
|
|
|
537
537
|
this.log.verbose(`Collected attestations from validators, number of attestations: ${attestations.length}`);
|
|
538
538
|
|
|
539
539
|
// note: the smart contract requires that the signatures are provided in the order of the committee
|
|
540
|
-
return
|
|
540
|
+
return orderAttestations(attestations, committee);
|
|
541
541
|
}
|
|
542
542
|
|
|
543
543
|
/**
|
|
@@ -666,12 +666,12 @@ export enum SequencerState {
|
|
|
666
666
|
*
|
|
667
667
|
* @todo: perform this logic within the memory attestation store instead?
|
|
668
668
|
*/
|
|
669
|
-
|
|
669
|
+
function orderAttestations(attestations: BlockAttestation[], orderAddresses: EthAddress[]): Signature[] {
|
|
670
670
|
// Create a map of sender addresses to BlockAttestations
|
|
671
671
|
const attestationMap = new Map<string, BlockAttestation>();
|
|
672
672
|
|
|
673
673
|
for (const attestation of attestations) {
|
|
674
|
-
const sender =
|
|
674
|
+
const sender = attestation.getSender();
|
|
675
675
|
if (sender) {
|
|
676
676
|
attestationMap.set(sender.toString(), attestation);
|
|
677
677
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PublicKernelPhase, type Tx, type TxValidator } from '@aztec/circuit-types';
|
|
2
2
|
import { type AztecAddress, type Fr } from '@aztec/circuits.js';
|
|
3
3
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
4
4
|
import { FeeJuiceArtifact } from '@aztec/protocol-contracts/fee-juice';
|
|
5
|
-
import {
|
|
5
|
+
import { EnqueuedCallsProcessor, computeFeePayerBalanceStorageSlot } from '@aztec/simulator';
|
|
6
6
|
|
|
7
7
|
/** Provides a view into public contract state */
|
|
8
8
|
export interface PublicStateSource {
|
|
@@ -34,6 +34,10 @@ export class GasTxValidator implements TxValidator<Tx> {
|
|
|
34
34
|
return [validTxs, invalidTxs];
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
validateTx(tx: Tx): Promise<boolean> {
|
|
38
|
+
return this.#validateTxFee(tx);
|
|
39
|
+
}
|
|
40
|
+
|
|
37
41
|
async #validateTxFee(tx: Tx): Promise<boolean> {
|
|
38
42
|
const feePayer = tx.data.feePayer;
|
|
39
43
|
// TODO(@spalladino) Eventually remove the is_zero condition as we should always charge fees to every tx
|
|
@@ -55,7 +59,7 @@ export class GasTxValidator implements TxValidator<Tx> {
|
|
|
55
59
|
);
|
|
56
60
|
|
|
57
61
|
// If there is a claim in this tx that increases the fee payer balance in Fee Juice, add it to balance
|
|
58
|
-
const
|
|
62
|
+
const setupFns = EnqueuedCallsProcessor.getExecutionRequestsByPhase(tx, PublicKernelPhase.SETUP);
|
|
59
63
|
const claimFunctionCall = setupFns.find(
|
|
60
64
|
fn =>
|
|
61
65
|
fn.contractAddress.equals(this.#feeJuiceAddress) &&
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type AllowedElement,
|
|
3
3
|
type PublicExecutionRequest,
|
|
4
|
-
|
|
4
|
+
PublicKernelPhase,
|
|
5
5
|
Tx,
|
|
6
6
|
type TxValidator,
|
|
7
7
|
} from '@aztec/circuit-types';
|
|
8
8
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
9
|
-
import {
|
|
9
|
+
import { ContractsDataSourcePublicDB, EnqueuedCallsProcessor } from '@aztec/simulator';
|
|
10
10
|
import { type ContractDataSource } from '@aztec/types/contracts';
|
|
11
11
|
|
|
12
12
|
export class PhasesTxValidator implements TxValidator<Tx> {
|
|
@@ -27,7 +27,7 @@ export class PhasesTxValidator implements TxValidator<Tx> {
|
|
|
27
27
|
// which is what we're trying to do as part of the current txs.
|
|
28
28
|
await this.contractDataSource.addNewContracts(tx);
|
|
29
29
|
|
|
30
|
-
if (await this
|
|
30
|
+
if (await this.validateTx(tx)) {
|
|
31
31
|
validTxs.push(tx);
|
|
32
32
|
} else {
|
|
33
33
|
invalidTxs.push(tx);
|
|
@@ -39,14 +39,13 @@ export class PhasesTxValidator implements TxValidator<Tx> {
|
|
|
39
39
|
return Promise.resolve([validTxs, invalidTxs]);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
async
|
|
42
|
+
async validateTx(tx: Tx): Promise<boolean> {
|
|
43
43
|
if (!tx.data.forPublic) {
|
|
44
44
|
this.#log.debug(`Tx ${Tx.getHash(tx)} does not contain enqueued public functions. Skipping phases validation.`);
|
|
45
45
|
return true;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
const
|
|
49
|
-
|
|
48
|
+
const setupFns = EnqueuedCallsProcessor.getExecutionRequestsByPhase(tx, PublicKernelPhase.SETUP);
|
|
50
49
|
for (const setupFn of setupFns) {
|
|
51
50
|
if (!(await this.isOnAllowList(setupFn, this.setupAllowList))) {
|
|
52
51
|
this.#log.warn(
|
|
@@ -32,9 +32,9 @@ function patchFn(
|
|
|
32
32
|
tx.enqueuedPublicFunctionCalls[index] = fn;
|
|
33
33
|
|
|
34
34
|
const request = tx.data.forPublic![where].publicCallStack[index];
|
|
35
|
-
request.
|
|
36
|
-
request.
|
|
37
|
-
request.
|
|
35
|
+
request.contractAddress = fn.contractAddress;
|
|
36
|
+
request.callContext = fn.callContext;
|
|
37
|
+
request.argsHash = computeVarArgsHash(fn.args);
|
|
38
38
|
tx.data.forPublic![where].publicCallStack[index] = request;
|
|
39
39
|
|
|
40
40
|
return {
|
|
@@ -2,7 +2,7 @@ import { type AllowedElement, type ProcessedTx, type Tx, type TxValidator } from
|
|
|
2
2
|
import { type GlobalVariables } from '@aztec/circuits.js';
|
|
3
3
|
import { AggregateTxValidator, DataTxValidator, DoubleSpendTxValidator, MetadataTxValidator } from '@aztec/p2p';
|
|
4
4
|
import { FeeJuiceAddress } from '@aztec/protocol-contracts/fee-juice';
|
|
5
|
-
import { WorldStateDB
|
|
5
|
+
import { WorldStateDB } from '@aztec/simulator';
|
|
6
6
|
import { type ContractDataSource } from '@aztec/types/contracts';
|
|
7
7
|
import { type MerkleTreeOperations } from '@aztec/world-state';
|
|
8
8
|
|
|
@@ -17,16 +17,17 @@ export class TxValidatorFactory {
|
|
|
17
17
|
) {}
|
|
18
18
|
|
|
19
19
|
validatorForNewTxs(globalVariables: GlobalVariables, setupAllowList: AllowedElement[]): TxValidator<Tx> {
|
|
20
|
+
const worldStateDB = new WorldStateDB(this.merkleTreeDb, this.contractDataSource);
|
|
20
21
|
return new AggregateTxValidator(
|
|
21
22
|
new DataTxValidator(),
|
|
22
23
|
new MetadataTxValidator(globalVariables.chainId, globalVariables.blockNumber),
|
|
23
|
-
new DoubleSpendTxValidator(
|
|
24
|
+
new DoubleSpendTxValidator(worldStateDB),
|
|
24
25
|
new PhasesTxValidator(this.contractDataSource, setupAllowList),
|
|
25
|
-
new GasTxValidator(
|
|
26
|
+
new GasTxValidator(worldStateDB, FeeJuiceAddress, this.enforceFees),
|
|
26
27
|
);
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
validatorForProcessedTxs(): TxValidator<ProcessedTx> {
|
|
30
|
-
return new DoubleSpendTxValidator(new WorldStateDB(this.merkleTreeDb));
|
|
31
|
+
return new DoubleSpendTxValidator(new WorldStateDB(this.merkleTreeDb, this.contractDataSource));
|
|
31
32
|
}
|
|
32
33
|
}
|