Skip to content

Commit

Permalink
chore: Revert to current date as timestamp for devnet
Browse files Browse the repository at this point in the history
When running devnet, using the slot timestamps instead of current
timestmap meant that blocks were often generated with a timestamp much
into the future. This screwed up settings such as the min and max time
between blocks for a sequencer configuration. In addition, the custom
block timestamp interval in anvil meant that we could no longer rely on
L1 timestamps for measuring time, which was needed for tracking the time
between a block being submitted and its proof.

This PR changes timestamps if devnet is set so that we use the current
timestamp for building blocks, do not alter anvil's block timestamp, and
drop time validations.
  • Loading branch information
spalladino committed Aug 26, 2024
1 parent bfbc4b2 commit 4780b21
Show file tree
Hide file tree
Showing 13 changed files with 143 additions and 25 deletions.
24 changes: 13 additions & 11 deletions l1-contracts/src/core/Rollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -585,19 +585,21 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
revert Errors.Rollup__InvalidArchive(tipArchive, _header.lastArchive.root);
}

uint256 slot = _header.globalVariables.slotNumber;
if (slot > type(uint128).max) {
revert Errors.Rollup__SlotValueTooLarge(slot);
}
if (!isDevNet) {
uint256 slot = _header.globalVariables.slotNumber;
if (slot > type(uint128).max) {
revert Errors.Rollup__SlotValueTooLarge(slot);
}

uint256 lastSlot = uint256(blocks[pendingBlockCount - 1].slotNumber);
if (slot <= lastSlot) {
revert Errors.Rollup__SlotAlreadyInChain(lastSlot, slot);
}
uint256 lastSlot = uint256(blocks[pendingBlockCount - 1].slotNumber);
if (slot <= lastSlot) {
revert Errors.Rollup__SlotAlreadyInChain(lastSlot, slot);
}

uint256 timestamp = getTimestampForSlot(slot);
if (_header.globalVariables.timestamp != timestamp) {
revert Errors.Rollup__InvalidTimestamp(timestamp, _header.globalVariables.timestamp);
uint256 timestamp = getTimestampForSlot(slot);
if (_header.globalVariables.timestamp != timestamp) {
revert Errors.Rollup__InvalidTimestamp(timestamp, _header.globalVariables.timestamp);
}
}

// Check if the data is available using availability oracle (change availability oracle if you want a different DA layer)
Expand Down
10 changes: 8 additions & 2 deletions yarn-project/aztec-node/src/aztec-node/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,13 @@ 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, GlobalVariableBuilder, SequencerClient } from '@aztec/sequencer-client';
import {
AggregateTxValidator,
DataTxValidator,
type GlobalVariableBuilder,
SequencerClient,
createGlobalVariableBuilder,
} 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 @@ -195,7 +201,7 @@ export class AztecNodeService implements AztecNode {
sequencer,
ethereumChain.chainInfo.id,
config.version,
new GlobalVariableBuilder(config),
createGlobalVariableBuilder(config),
store,
txValidator,
telemetry,
Expand Down
2 changes: 2 additions & 0 deletions yarn-project/aztec/src/sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { type AztecNodeConfig, AztecNodeService, getConfigEnvVars } from '@aztec
import { SignerlessWallet } from '@aztec/aztec.js';
import { DefaultMultiCallEntrypoint } from '@aztec/aztec.js/entrypoint';
import { type AztecNode } from '@aztec/circuit-types';
import { IS_DEV_NET } from '@aztec/circuits.js';
import { deployCanonicalAuthRegistry, deployCanonicalKeyRegistry, deployCanonicalL2FeeJuice } from '@aztec/cli/misc';
import {
type DeployL1Contracts,
Expand Down Expand Up @@ -133,6 +134,7 @@ export async function deployContractsToL1(
vkTreeRoot: getVKTreeRoot(),
assumeProvenUntil: opts.assumeProvenUntilBlockNumber,
salt: undefined,
blockInterval: IS_DEV_NET ? undefined : 12,
}),
);

Expand Down
2 changes: 2 additions & 0 deletions yarn-project/cli/src/utils/aztec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { type ContractArtifact, type FunctionArtifact, loadContractArtifact } from '@aztec/aztec.js/abi';
import { type L1ContractArtifactsForDeployment } from '@aztec/aztec.js/ethereum';
import { type PXE } from '@aztec/circuit-types';
import { IS_DEV_NET } from '@aztec/circuits.js';
import { type DeployL1Contracts } from '@aztec/ethereum';
import { type EthAddress } from '@aztec/foundation/eth-address';
import { type DebugLogger, type LogFn } from '@aztec/foundation/log';
Expand Down Expand Up @@ -118,6 +119,7 @@ export async function deployAztecContracts(
l2FeeJuiceAddress: FeeJuiceAddress,
vkTreeRoot: getVKTreeRoot(),
salt,
blockInterval: IS_DEV_NET ? undefined : 12,
});
}

Expand Down
2 changes: 2 additions & 0 deletions yarn-project/end-to-end/src/fixtures/setup_l1_contracts.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type DebugLogger, type L1ContractArtifactsForDeployment, deployL1Contracts } from '@aztec/aztec.js';
import { IS_DEV_NET } from '@aztec/circuits.js';
import {
AvailabilityOracleAbi,
AvailabilityOracleBytecode,
Expand Down Expand Up @@ -63,6 +64,7 @@ export const setupL1Contracts = async (
l2FeeJuiceAddress: FeeJuiceAddress,
vkTreeRoot: getVKTreeRoot(),
salt: undefined,
blockInterval: IS_DEV_NET ? undefined : 12,
});

return l1Data;
Expand Down
2 changes: 2 additions & 0 deletions yarn-project/end-to-end/src/fixtures/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
CANONICAL_AUTH_REGISTRY_ADDRESS,
CANONICAL_KEY_REGISTRY_ADDRESS,
GasSettings,
IS_DEV_NET,
MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS,
computeContractAddressFromInstance,
getContractClassFromArtifact,
Expand Down Expand Up @@ -149,6 +150,7 @@ export const setupL1Contracts = async (
l2FeeJuiceAddress: FeeJuiceAddress,
vkTreeRoot: getVKTreeRoot(),
salt: args.salt,
blockInterval: IS_DEV_NET ? undefined : 12,
});

return l1Data;
Expand Down
20 changes: 14 additions & 6 deletions yarn-project/ethereum/src/deploy_l1_contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,13 @@ export const deployL1Contracts = async (
chain: Chain,
logger: DebugLogger,
contractsToDeploy: L1ContractArtifactsForDeployment,
args: { l2FeeJuiceAddress: AztecAddress; vkTreeRoot: Fr; assumeProvenUntil?: number; salt: number | undefined },
args: {
blockInterval: number | undefined;
l2FeeJuiceAddress: AztecAddress;
vkTreeRoot: Fr;
assumeProvenUntil?: number;
salt: number | undefined;
},
): Promise<DeployL1Contracts> => {
// We are assuming that you are running this on a local anvil node which have 1s block times
// To align better with actual deployment, we update the block interval to 12s
Expand All @@ -161,12 +167,14 @@ export const deployL1Contracts = async (
};
return await (await fetch(rpcUrl, content)).json();
};
const interval = 12;
const res = await rpcCall(rpcUrl, 'anvil_setBlockTimestampInterval', [interval]);
if (res.error) {
throw new Error(`Error setting block interval: ${res.error.message}`);

if (args.blockInterval !== undefined) {
const res = await rpcCall(rpcUrl, 'anvil_setBlockTimestampInterval', [args.blockInterval]);
if (res.error) {
throw new Error(`Error setting block interval: ${res.error.message}`);
}
logger.info(`Set block interval to ${args.blockInterval}`);
}
logger.info(`Set block interval to ${interval}`);

logger.info(`Deploying contracts from ${account.address.toString()}...`);

Expand Down
4 changes: 2 additions & 2 deletions yarn-project/sequencer-client/src/client/sequencer-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { type WorldStateSynchronizer } from '@aztec/world-state';

import { BlockBuilderFactory } from '../block_builder/index.js';
import { type SequencerClientConfig } from '../config.js';
import { GlobalVariableBuilder } from '../global_variable_builder/index.js';
import { createGlobalVariableBuilder } 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 @@ -44,7 +44,7 @@ export class SequencerClient {
telemetryClient: TelemetryClient,
) {
const publisher = new L1Publisher(config, telemetryClient);
const globalsBuilder = new GlobalVariableBuilder(config);
const globalsBuilder = createGlobalVariableBuilder(config);
const merkleTreeDb = worldStateSynchronizer.getLatest();

const publicProcessorFactory = new PublicProcessorFactory(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { type AztecAddress, type EthAddress, 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';

/**
* Simple global variables builder for devnet. Uses current timestamp and slots equal to block numbers.
*/
export class DevnetGlobalVariableBuilder {
private log = createDebugLogger('aztec:sequencer:devnet_global_variable_builder');

private rollupContract: GetContractReturnType<typeof RollupAbi, PublicClient<HttpTransport, chains.Chain>>;
private publicClient: PublicClient<HttpTransport, chains.Chain>;

constructor(config: L1ReaderConfig) {
const { l1RpcUrl, l1ChainId: chainId, l1Contracts } = config;

const chain = createEthereumChain(l1RpcUrl, chainId);

this.publicClient = createPublicClient({
chain: chain.chainInfo,
transport: http(chain.rpcUrl),
});

this.rollupContract = getContract({
address: getAddress(l1Contracts.rollupAddress.toString()),
abi: RollupAbi,
client: this.publicClient,
});
}

/**
* Simple builder of global variables that use the minimum time possible.
* @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.
*/
public async buildGlobalVariables(
blockNumber: Fr,
coinbase: EthAddress,
feeRecipient: AztecAddress,
): Promise<GlobalVariables> {
const version = new Fr(await this.rollupContract.read.VERSION());
const chainId = new Fr(this.publicClient.chain.id);
const timestamp = new Fr(Math.floor(Date.now() / 1000));
const slot = blockNumber;

const gasFees = GasFees.default();
const globalVariables = new GlobalVariables(
chainId,
version,
blockNumber,
slot,
timestamp,
coinbase,
feeRecipient,
gasFees,
);
this.log.debug(`Built global variables for block ${blockNumber}`, globalVariables.toJSON());
return globalVariables;
}
}
Original file line number Diff line number Diff line change
@@ -1 +1,19 @@
export { GlobalVariableBuilder } from './global_builder.js';
import { type AztecAddress, type EthAddress, type GlobalVariables } from '@aztec/circuits.js';
import { IS_DEV_NET } from '@aztec/circuits.js';
import { type L1ReaderConfig } from '@aztec/ethereum';
import { type Fr } from '@aztec/foundation/fields';

import { DevnetGlobalVariableBuilder } from './devnet_global_builder.js';
import { SimpleGlobalVariableBuilder } from './simple_global_builder.js';

export { DevnetGlobalVariableBuilder } from './devnet_global_builder.js';
export { SimpleGlobalVariableBuilder } from './simple_global_builder.js';

export function createGlobalVariableBuilder(config: L1ReaderConfig): GlobalVariableBuilder {
return IS_DEV_NET ? new DevnetGlobalVariableBuilder(config) : new SimpleGlobalVariableBuilder(config);
}

/** Builds global variables for a block. */
export interface GlobalVariableBuilder {
buildGlobalVariables(blockNumber: Fr, coinbase: EthAddress, feeRecipient: AztecAddress): Promise<GlobalVariables>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import type * as chains from 'viem/chains';
/**
* Simple global variables builder.
*/
export class GlobalVariableBuilder {
export class SimpleGlobalVariableBuilder {
private log = createDebugLogger('aztec:sequencer:global_variable_builder');

private rollupContract: GetContractReturnType<typeof RollupAbi, PublicClient<HttpTransport, chains.Chain>>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import { type MerkleTreeOperations, WorldStateRunningState, type WorldStateSynch
import { type MockProxy, mock, mockFn } from 'jest-mock-extended';

import { type BlockBuilderFactory } from '../block_builder/index.js';
import { type GlobalVariableBuilder } from '../global_variable_builder/global_builder.js';
import { type GlobalVariableBuilder } from '../global_variable_builder/index.js';
import { type L1Publisher } from '../publisher/l1-publisher.js';
import { TxValidatorFactory } from '../tx_validator/tx_validator_factory.js';
import { Sequencer } from './sequencer.js';
Expand Down
3 changes: 2 additions & 1 deletion yarn-project/sequencer-client/src/sequencer/sequencer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { type ValidatorClient } from '@aztec/validator-client';
import { type WorldStateStatus, type WorldStateSynchronizer } from '@aztec/world-state';

import { type BlockBuilderFactory } from '../block_builder/index.js';
import { type GlobalVariableBuilder } from '../global_variable_builder/global_builder.js';
import { type GlobalVariableBuilder } from '../global_variable_builder/index.js';
import { type L1Publisher } from '../publisher/l1-publisher.js';
import { type TxValidatorFactory } from '../tx_validator/tx_validator_factory.js';
import { type SequencerConfig } from './config.js';
Expand Down Expand Up @@ -244,6 +244,7 @@ export class Sequencer {
this._coinbase,
this._feeRecipient,
);
this.log.warn(`BUILD GLOBALS ${new Date(newGlobalVariables.timestamp.toNumber() * 1000)}`);

// @todo @LHerskind Include some logic to consider slots

Expand Down

0 comments on commit 4780b21

Please sign in to comment.