Skip to content

Commit

Permalink
refactor: simplify sequencer and l1 communication (#7989)
Browse files Browse the repository at this point in the history
Fixes #7821. 

Looking to combine some of the components where there are interfaces
that don't really seem to be useful as there would likely be only one
implementation. When makes sense, I have joined the "wrapper" and the
thing it wrapped because extra wrapping is just confusing.

Starting with changing the global variables builder, since that was low
hanging. When looking at the `viem-tx-sender` it is more tedious as the
tests are heavily abusing that had two separate components.

Getting rid of the `gasEstimate` steps as viem seems to perform that
estimate step if no gas amount is provided, so might as well make it
less verbose, https://viem.sh/docs/contract/writeContract#gas-optional.

- Removes the `viem-reader`
- Removes the `viem-tx-sender`
- Removes the `receiver`
- Alter the `GlobalVariableBuilder` to directly read values
- Alter the `L1Publisher` to interact directly with the rollup and
availability oracle.
- Updates the tests
  • Loading branch information
LHerskind authored Aug 19, 2024
1 parent 8821e5f commit cee4eba
Show file tree
Hide file tree
Showing 13 changed files with 405 additions and 622 deletions.
10 changes: 2 additions & 8 deletions yarn-project/aztec-node/src/aztec-node/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,7 @@ import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice';
import { getCanonicalInstanceDeployer } from '@aztec/protocol-contracts/instance-deployer';
import { getCanonicalKeyRegistryAddress } from '@aztec/protocol-contracts/key-registry';
import { getCanonicalMultiCallEntrypointAddress } from '@aztec/protocol-contracts/multi-call-entrypoint';
import {
AggregateTxValidator,
DataTxValidator,
type GlobalVariableBuilder,
SequencerClient,
getGlobalVariableBuilder,
} from '@aztec/sequencer-client';
import { AggregateTxValidator, DataTxValidator, GlobalVariableBuilder, SequencerClient } from '@aztec/sequencer-client';
import { PublicProcessorFactory, WASMSimulator, createSimulationProvider } from '@aztec/simulator';
import { type TelemetryClient } from '@aztec/telemetry-client';
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
Expand Down Expand Up @@ -202,7 +196,7 @@ export class AztecNodeService implements AztecNode {
sequencer,
ethereumChain.chainInfo.id,
config.version,
getGlobalVariableBuilder(config),
new GlobalVariableBuilder(config),
store,
txValidator,
telemetry,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import { AvailabilityOracleAbi, OutboxAbi, RollupAbi } from '@aztec/l1-artifacts
import { SHA256Trunc, StandardTree } from '@aztec/merkle-tree';
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types';
import { TxProver } from '@aztec/prover-client';
import { type L1Publisher, getL1Publisher } from '@aztec/sequencer-client';
import { L1Publisher } from '@aztec/sequencer-client';
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
import { MerkleTrees, ServerWorldStateSynchronizer, type WorldStateConfig } from '@aztec/world-state';

Expand Down Expand Up @@ -161,7 +161,7 @@ describe('L1Publisher integration', () => {
builder = await TxProver.new(config, new NoopTelemetryClient());
prover = builder.createBlockProver(builderDb.asLatest());

publisher = getL1Publisher(
publisher = new L1Publisher(
{
l1RpcUrl: config.l1RpcUrl,
requiredConfirmations: 1,
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/prover-node/src/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { type AztecNode } from '@aztec/circuit-types';
import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log';
import { createStore } from '@aztec/kv-store/utils';
import { createProverClient } from '@aztec/prover-client';
import { getL1Publisher } from '@aztec/sequencer-client';
import { L1Publisher } from '@aztec/sequencer-client';
import { createSimulationProvider } from '@aztec/simulator';
import { type TelemetryClient } from '@aztec/telemetry-client';
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
Expand Down Expand Up @@ -43,7 +43,7 @@ export async function createProverNode(
const prover = await createProverClient(config, telemetry);

// REFACTOR: Move publisher out of sequencer package and into an L1-related package
const publisher = getL1Publisher(config, telemetry);
const publisher = new L1Publisher(config, telemetry);

const txProvider = deps.aztecNodeTxProvider
? new AztecNodeTxProvider(deps.aztecNodeTxProvider)
Expand Down
8 changes: 4 additions & 4 deletions yarn-project/sequencer-client/src/client/sequencer-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { type WorldStateSynchronizer } from '@aztec/world-state';

import { BlockBuilderFactory } from '../block_builder/index.js';
import { type SequencerClientConfig } from '../config.js';
import { getGlobalVariableBuilder } from '../global_variable_builder/index.js';
import { getL1Publisher } from '../publisher/index.js';
import { GlobalVariableBuilder } from '../global_variable_builder/index.js';
import { L1Publisher } from '../publisher/index.js';
import { Sequencer, type SequencerConfig } from '../sequencer/index.js';
import { TxValidatorFactory } from '../tx_validator/tx_validator_factory.js';

Expand Down Expand Up @@ -43,8 +43,8 @@ export class SequencerClient {
simulationProvider: SimulationProvider,
telemetryClient: TelemetryClient,
) {
const publisher = getL1Publisher(config, telemetryClient);
const globalsBuilder = getGlobalVariableBuilder(config);
const publisher = new L1Publisher(config, telemetryClient);
const globalsBuilder = new GlobalVariableBuilder(config);
const merkleTreeDb = worldStateSynchronizer.getLatest();

const publicProcessorFactory = new PublicProcessorFactory(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,71 +5,47 @@ import {
GasFees,
GlobalVariables,
} from '@aztec/circuits.js';
import { type L1ReaderConfig, createEthereumChain } from '@aztec/ethereum';
import { Fr } from '@aztec/foundation/fields';
import { createDebugLogger } from '@aztec/foundation/log';
import { RollupAbi } from '@aztec/l1-artifacts';

import {
type GetContractReturnType,
type HttpTransport,
type PublicClient,
createPublicClient,
getAddress,
getContract,
http,
} from 'viem';
import type * as chains from 'viem/chains';

/**
* Reads values from L1 state that is used for the global values.
* Simple global variables builder.
*/
export interface L1GlobalReader {
/**
* Fetches the version of the rollup contract.
* @returns The version of the rollup contract.
*/
getVersion(): Promise<bigint>;
/**
* Gets the chain id.
* @returns The chain id.
*/
getChainId(): Promise<bigint>;

/**
* Gets the current L1 time.
* @returns The current L1 time.
*/
getL1CurrentTime(): Promise<bigint>;
export class GlobalVariableBuilder {
private log = createDebugLogger('aztec:sequencer:global_variable_builder');

/**
* Gets the current slot.
* @returns The current slot.
*/
getCurrentSlot(): Promise<bigint>;
private rollupContract: GetContractReturnType<typeof RollupAbi, PublicClient<HttpTransport, chains.Chain>>;
private publicClient: PublicClient<HttpTransport, chains.Chain>;

/**
* Get the slot for a specific timestamp.
* @param timestamp - The timestamp to get the slot for.
*/
getSlotAt(timestamp: readonly [bigint]): Promise<bigint>;
constructor(config: L1ReaderConfig) {
const { l1RpcUrl, l1ChainId: chainId, l1Contracts } = config;

/**
* Gets the timestamp for a slot
* @param slot - The slot to get the timestamp for.
* @returns The timestamp for the slot.
*/
getTimestampForSlot(slot: readonly [bigint]): Promise<bigint>;
}
const chain = createEthereumChain(l1RpcUrl, chainId);

/**
* Builds global variables from L1 state.
*/
export interface GlobalVariableBuilder {
/**
* Builds global variables.
* @param blockNumber - The block number to build global variables for.
* @param coinbase - The address to receive block reward.
* @param feeRecipient - The address to receive fees.
* @returns The global variables for the given block number.
*/
buildGlobalVariables(blockNumber: Fr, coinbase: EthAddress, feeRecipient: AztecAddress): Promise<GlobalVariables>;
}
this.publicClient = createPublicClient({
chain: chain.chainInfo,
transport: http(chain.rpcUrl),
});

/**
* Simple test implementation of a builder that uses the minimum time possible for the global variables.
* Also uses a "hack" to make use of the warp cheatcode that manipulates time on Aztec.
*/
export class SimpleTestGlobalVariableBuilder implements GlobalVariableBuilder {
private log = createDebugLogger('aztec:sequencer:simple_test_global_variable_builder');
constructor(private readonly reader: L1GlobalReader) {}
this.rollupContract = getContract({
address: getAddress(l1Contracts.rollupAddress.toString()),
abi: RollupAbi,
client: this.publicClient,
});
}

/**
* Simple builder of global variables that use the minimum time possible.
Expand All @@ -83,18 +59,18 @@ export class SimpleTestGlobalVariableBuilder implements GlobalVariableBuilder {
coinbase: EthAddress,
feeRecipient: AztecAddress,
): Promise<GlobalVariables> {
// Not just the current slot, the slot of the next block.
const ts = (await this.reader.getL1CurrentTime()) + BigInt(ETHEREUM_SLOT_DURATION);
const version = new Fr(await this.rollupContract.read.VERSION());
const chainId = new Fr(this.publicClient.chain.id);

const ts = (await this.publicClient.getBlock()).timestamp;

const slot = await this.reader.getSlotAt([ts]);
const timestamp = await this.reader.getTimestampForSlot([slot]);
// Not just the current slot, the slot of the next block.
const slot = await this.rollupContract.read.getSlotAt([ts + BigInt(ETHEREUM_SLOT_DURATION)]);
const timestamp = await this.rollupContract.read.getTimestampForSlot([slot]);

const slotFr = new Fr(slot);
const timestampFr = new Fr(timestamp);

const version = new Fr(await this.reader.getVersion());
const chainId = new Fr(await this.reader.getChainId());

const gasFees = GasFees.default();
const globalVariables = new GlobalVariables(
chainId,
Expand Down
15 changes: 0 additions & 15 deletions yarn-project/sequencer-client/src/global_variable_builder/index.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1 @@
import { type L1ReaderConfig } from '@aztec/ethereum';

import { type GlobalVariableBuilder, SimpleTestGlobalVariableBuilder } from './global_builder.js';
import { ViemReader } from './viem-reader.js';

export { SimpleTestGlobalVariableBuilder as SimpleGlobalVariableBuilder } from './global_builder.js';
export { GlobalVariableBuilder } from './global_builder.js';

/**
* Returns a new instance of the global variable builder.
* @param config - Configuration to initialize the builder.
* @returns A new instance of the global variable builder.
*/
export function getGlobalVariableBuilder(config: L1ReaderConfig): GlobalVariableBuilder {
return new SimpleTestGlobalVariableBuilder(new ViemReader(config));
}

This file was deleted.

14 changes: 0 additions & 14 deletions yarn-project/sequencer-client/src/publisher/index.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,2 @@
import { type TelemetryClient } from '@aztec/telemetry-client';

import { type PublisherConfig, type TxSenderConfig } from './config.js';
import { L1Publisher } from './l1-publisher.js';
import { ViemTxSender } from './viem-tx-sender.js';

export { L1Publisher } from './l1-publisher.js';
export * from './config.js';

/**
* Returns a new instance of the L1Publisher.
* @param config - Configuration to initialize the new instance.
*/
export function getL1Publisher(config: PublisherConfig & TxSenderConfig, client: TelemetryClient): L1Publisher {
return new L1Publisher(new ViemTxSender(config), client, config);
}
Loading

0 comments on commit cee4eba

Please sign in to comment.