From b6c45fee176a9478981b8750e45f51d2db2b59eb Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 18 Jan 2024 09:12:18 +0000 Subject: [PATCH 01/22] feat: publish block body separately --- l1-contracts/src/core/Rollup.sol | 18 +++++---------- l1-contracts/src/core/interfaces/IRollup.sol | 1 + l1-contracts/test/Rollup.t.sol | 23 +++++++++++++++----- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/l1-contracts/src/core/Rollup.sol b/l1-contracts/src/core/Rollup.sol index fbced8300d8a..b7781a6ad0ec 100644 --- a/l1-contracts/src/core/Rollup.sol +++ b/l1-contracts/src/core/Rollup.sol @@ -47,13 +47,14 @@ contract Rollup is IRollup { * @notice Process an incoming L2 block and progress the state * @param _header - The L2 block header * @param _archive - A root of the archive tree after the L2 block is applied - * @param _body - The L2 block body + * @param _txsHash - The L2 block body * @param _proof - The proof of correct execution */ function process( bytes calldata _header, bytes32 _archive, - bytes calldata _body, // TODO(#3944): this will be replaced with _txsHash once the separation is finished. + bytes32 _txsHash, // @todo @benesjan Update this to be actual txs hash and not the old diff root. + bytes calldata _body, // @todo @benesjan Update this to pass in only th messages and not the whole body. bytes memory _proof ) external override(IRollup) { // Decode and validate header @@ -61,16 +62,9 @@ contract Rollup is IRollup { HeaderLib.validate(header, VERSION, lastBlockTs, archive); // Check if the data is available using availability oracle (change availability oracle if you want a different DA layer) - bytes32 txsHash; - { - // @todo @LHerskind Hack such that the node is unchanged for now. - // should be removed when we have a proper block publication. - txsHash = AVAILABILITY_ORACLE.publish(_body); - } - - if (!AVAILABILITY_ORACLE.isAvailable(txsHash)) { + if (!AVAILABILITY_ORACLE.isAvailable(_txsHash)) { // @todo @LHerskind Impossible to hit with above hack. - revert Errors.Rollup__UnavailableTxs(txsHash); + revert Errors.Rollup__UnavailableTxs(_txsHash); } // Decode the cross-chain messages @@ -78,7 +72,7 @@ contract Rollup is IRollup { MessagesDecoder.decode(_body); bytes32[] memory publicInputs = new bytes32[](1); - publicInputs[0] = _computePublicInputHash(_header, txsHash, inHash); + publicInputs[0] = _computePublicInputHash(_header, _txsHash, inHash); // @todo @benesjan We will need `nextAvailableLeafIndex` of archive to verify the proof. This value is equal to // current block number which is stored in the header (header.globalVariables.blockNumber). diff --git a/l1-contracts/src/core/interfaces/IRollup.sol b/l1-contracts/src/core/interfaces/IRollup.sol index 47f6dd8b31a1..804e3bf13e98 100644 --- a/l1-contracts/src/core/interfaces/IRollup.sol +++ b/l1-contracts/src/core/interfaces/IRollup.sol @@ -8,6 +8,7 @@ interface IRollup { function process( bytes calldata _header, bytes32 _archive, + bytes32 _txsHash, bytes calldata _body, bytes memory _proof ) external; diff --git a/l1-contracts/test/Rollup.t.sol b/l1-contracts/test/Rollup.t.sol index 382908012f1a..3d3bd6f6ff2a 100644 --- a/l1-contracts/test/Rollup.t.sol +++ b/l1-contracts/test/Rollup.t.sol @@ -16,6 +16,7 @@ import {Inbox} from "../src/core/messagebridge/Inbox.sol"; import {Outbox} from "../src/core/messagebridge/Outbox.sol"; import {Errors} from "../src/core/libraries/Errors.sol"; import {Rollup} from "../src/core/Rollup.sol"; +import {AvailabilityOracle} from "../src/core/availability_oracle/AvailabilityOracle.sol"; /** * Blocks are generated using the `integration_l1_publisher.test.ts` tests. @@ -27,6 +28,7 @@ contract RollupTest is DecoderBase { Inbox internal inbox; Outbox internal outbox; Rollup internal rollup; + AvailabilityOracle internal availabilityOracle; function setUp() public virtual { helper = new DecoderHelper(); @@ -35,6 +37,7 @@ contract RollupTest is DecoderBase { inbox = new Inbox(address(registry)); outbox = new Outbox(address(registry)); rollup = new Rollup(registry); + availabilityOracle = rollup.AVAILABILITY_ORACLE(); registry.upgrade(address(rollup), address(inbox), address(outbox)); } @@ -67,8 +70,10 @@ contract RollupTest is DecoderBase { mstore(add(header, 0x20), 0x420) } + bytes32 txsHash = availabilityOracle.publish(body); + vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidChainId.selector, 0x420, 31337)); - rollup.process(header, archive, body, bytes("")); + rollup.process(header, archive, txsHash, body, bytes("")); } function testRevertInvalidVersion() public { @@ -81,8 +86,10 @@ contract RollupTest is DecoderBase { mstore(add(header, 0x40), 0x420) } + bytes32 txsHash = availabilityOracle.publish(body); + vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidVersion.selector, 0x420, 1)); - rollup.process(header, archive, body, bytes("")); + rollup.process(header, archive, txsHash, body, bytes("")); } function testRevertTimestampInFuture() public { @@ -96,8 +103,10 @@ contract RollupTest is DecoderBase { mstore(add(header, 0x80), ts) } + bytes32 txsHash = availabilityOracle.publish(body); + vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__TimestampInFuture.selector)); - rollup.process(header, archive, body, bytes("")); + rollup.process(header, archive, txsHash, body, bytes("")); } function testRevertTimestampTooOld() public { @@ -109,8 +118,10 @@ contract RollupTest is DecoderBase { // Overwrite in the rollup contract vm.store(address(rollup), bytes32(uint256(1)), bytes32(uint256(block.timestamp))); + bytes32 txsHash = availabilityOracle.publish(body); + vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__TimestampTooOld.selector)); - rollup.process(header, archive, body, bytes("")); + rollup.process(header, archive, txsHash, body, bytes("")); } function _testBlock(string memory name) public { @@ -131,8 +142,10 @@ contract RollupTest is DecoderBase { assertTrue(inbox.contains(full.messages.l1ToL2Messages[i]), "msg not in inbox"); } + bytes32 txsHash = availabilityOracle.publish(body); + vm.record(); - rollup.process(header, archive, body, bytes("")); + rollup.process(header, archive, txsHash, body, bytes("")); (, bytes32[] memory inboxWrites) = vm.accesses(address(inbox)); (, bytes32[] memory outboxWrites) = vm.accesses(address(outbox)); From 810d63abfef4f298a7d27a314b5a86fe11d4399e Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 18 Jan 2024 09:43:58 +0000 Subject: [PATCH 02/22] fixes --- l1-contracts/src/core/Rollup.sol | 7 ++++--- yarn-project/archiver/src/archiver/archiver.test.ts | 7 ++++++- yarn-project/archiver/src/archiver/eth_log_handlers.ts | 2 +- .../end-to-end/src/integration_l1_publisher.test.ts | 2 ++ .../sequencer-client/src/publisher/l1-publisher.ts | 3 +++ .../sequencer-client/src/publisher/viem-tx-sender.ts | 1 + 6 files changed, 17 insertions(+), 5 deletions(-) diff --git a/l1-contracts/src/core/Rollup.sol b/l1-contracts/src/core/Rollup.sol index b7781a6ad0ec..51911d0b7e3c 100644 --- a/l1-contracts/src/core/Rollup.sol +++ b/l1-contracts/src/core/Rollup.sol @@ -47,14 +47,15 @@ contract Rollup is IRollup { * @notice Process an incoming L2 block and progress the state * @param _header - The L2 block header * @param _archive - A root of the archive tree after the L2 block is applied - * @param _txsHash - The L2 block body + * @param _txsHash - Transactions hash. + * @param _body - The L2 block body * @param _proof - The proof of correct execution */ function process( bytes calldata _header, bytes32 _archive, - bytes32 _txsHash, // @todo @benesjan Update this to be actual txs hash and not the old diff root. - bytes calldata _body, // @todo @benesjan Update this to pass in only th messages and not the whole body. + bytes32 _txsHash, // TODO(#3938) Update this to be actual txs hash and not the old diff root. + bytes calldata _body, // TODO(#3938) Update this to pass in only th messages and not the whole body. bytes memory _proof ) external override(IRollup) { // Decode and validate header diff --git a/yarn-project/archiver/src/archiver/archiver.test.ts b/yarn-project/archiver/src/archiver/archiver.test.ts index 5fb5ef1fbb04..612281c3789c 100644 --- a/yarn-project/archiver/src/archiver/archiver.test.ts +++ b/yarn-project/archiver/src/archiver/archiver.test.ts @@ -351,8 +351,13 @@ function makeL1ToL2MessageCancelledEvents(l1BlockNum: bigint, entryKeys: string[ function makeRollupTx(l2Block: L2Block) { const header = toHex(l2Block.header.toBuffer()); const archive = toHex(l2Block.archive.root.toBuffer()); + const txsHash = toHex(l2Block.getCalldataHash()); const body = toHex(l2Block.bodyToBuffer()); const proof = `0x`; - const input = encodeFunctionData({ abi: RollupAbi, functionName: 'process', args: [header, archive, body, proof] }); + const input = encodeFunctionData({ + abi: RollupAbi, + functionName: 'process', + args: [header, archive, txsHash, body, proof], + }); return { input } as Transaction; } diff --git a/yarn-project/archiver/src/archiver/eth_log_handlers.ts b/yarn-project/archiver/src/archiver/eth_log_handlers.ts index 8ebf5d65433c..0d28ca2b4b23 100644 --- a/yarn-project/archiver/src/archiver/eth_log_handlers.ts +++ b/yarn-project/archiver/src/archiver/eth_log_handlers.ts @@ -107,7 +107,7 @@ async function getBlockFromCallData( if (functionName !== 'process') { throw new Error(`Unexpected method called ${functionName}`); } - const [headerHex, archiveRootHex, bodyHex] = args! as [Hex, Hex, Hex, Hex]; + const [headerHex, archiveRootHex, , bodyHex] = args! as [Hex, Hex, Hex, Hex, Hex]; const blockBuffer = Buffer.concat([ Buffer.from(hexToBytes(headerHex)), Buffer.from(hexToBytes(archiveRootHex)), // L2Block.archive.root diff --git a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts index df7f94163690..be9d3ddad02c 100644 --- a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts +++ b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts @@ -407,6 +407,7 @@ describe('L1Publisher integration', () => { args: [ `0x${block.header.toBuffer().toString('hex')}`, `0x${block.archive.root.toBuffer().toString('hex')}`, + `0x${block.getCalldataHash().toString('hex')}`, `0x${block.bodyToBuffer().toString('hex')}`, `0x${l2Proof.toString('hex')}`, ], @@ -475,6 +476,7 @@ describe('L1Publisher integration', () => { args: [ `0x${block.header.toBuffer().toString('hex')}`, `0x${block.archive.root.toBuffer().toString('hex')}`, + `0x${block.getCalldataHash().toString('hex')}`, `0x${block.bodyToBuffer().toString('hex')}`, `0x${l2Proof.toString('hex')}`, ], diff --git a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts index 2210aa32b6fc..1ddd02c92749 100644 --- a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts +++ b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts @@ -89,6 +89,8 @@ export type L1ProcessArgs = { header: Buffer; /** A root of the archive tree after the L2 block is applied. */ archive: Buffer; + /** Transactions hash. */ + txsHash: Buffer; /** L2 block body. */ body: Buffer; /** Root rollup proof of the L2 block. */ @@ -132,6 +134,7 @@ export class L1Publisher implements L2BlockReceiver { const txData = { header: block.header.toBuffer(), archive: block.archive.root.toBuffer(), + txsHash: block.getCalldataHash(), body: block.bodyToBuffer(), proof: Buffer.alloc(0), }; diff --git a/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts b/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts index 8d5118df410c..c592393118b3 100644 --- a/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts +++ b/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts @@ -125,6 +125,7 @@ export class ViemTxSender implements L1PublisherTxSender { const args = [ `0x${encodedData.header.toString('hex')}`, `0x${encodedData.archive.toString('hex')}`, + `0x${encodedData.txsHash.toString('hex')}`, `0x${encodedData.body.toString('hex')}`, `0x${encodedData.proof.toString('hex')}`, ] as const; From 6419103db652e5596cee4b50d5e7645ba5f54795 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 18 Jan 2024 10:36:13 +0000 Subject: [PATCH 03/22] WIP --- yarn-project/archiver/src/archiver/config.ts | 4 + .../aztec.js/src/contract/contract.test.ts | 1 + yarn-project/cli/src/utils.ts | 5 ++ .../ethereum/src/deploy_l1_contracts.ts | 13 ++++ .../ethereum/src/l1_contract_addresses.ts | 4 + .../scripts/generate-artifacts.sh | 1 + .../src/pxe_service/test/pxe_service.test.ts | 1 + yarn-project/sequencer-client/src/config.ts | 4 + .../src/publisher/l1-publisher.ts | 76 ++++++++++++++++--- .../src/publisher/viem-tx-sender.ts | 31 +++++++- 10 files changed, 127 insertions(+), 13 deletions(-) diff --git a/yarn-project/archiver/src/archiver/config.ts b/yarn-project/archiver/src/archiver/config.ts index 6ec2e2fa9945..9c83ab13072c 100644 --- a/yarn-project/archiver/src/archiver/config.ts +++ b/yarn-project/archiver/src/archiver/config.ts @@ -56,6 +56,7 @@ export function getConfigEnvVars(): ArchiverConfig { ETHEREUM_HOST, ARCHIVER_POLLING_INTERVAL_MS, ARCHIVER_VIEM_POLLING_INTERVAL_MS, + AVAILABILITY_ORACLE_CONTRACT_ADDRESS, ROLLUP_CONTRACT_ADDRESS, CONTRACT_DEPLOYMENT_EMITTER_ADDRESS, API_KEY, @@ -66,6 +67,9 @@ export function getConfigEnvVars(): ArchiverConfig { } = process.env; // Populate the relevant addresses for use by the archiver. const addresses: L1ContractAddresses = { + availabilityOracleAddress: AVAILABILITY_ORACLE_CONTRACT_ADDRESS + ? EthAddress.fromString(AVAILABILITY_ORACLE_CONTRACT_ADDRESS) + : EthAddress.ZERO, rollupAddress: ROLLUP_CONTRACT_ADDRESS ? EthAddress.fromString(ROLLUP_CONTRACT_ADDRESS) : EthAddress.ZERO, registryAddress: REGISTRY_CONTRACT_ADDRESS ? EthAddress.fromString(REGISTRY_CONTRACT_ADDRESS) : EthAddress.ZERO, inboxAddress: INBOX_CONTRACT_ADDRESS ? EthAddress.fromString(INBOX_CONTRACT_ADDRESS) : EthAddress.ZERO, diff --git a/yarn-project/aztec.js/src/contract/contract.test.ts b/yarn-project/aztec.js/src/contract/contract.test.ts index f9800982b056..3ea687ebd7ea 100644 --- a/yarn-project/aztec.js/src/contract/contract.test.ts +++ b/yarn-project/aztec.js/src/contract/contract.test.ts @@ -21,6 +21,7 @@ describe('Contract Class', () => { const mockTxReceipt = { type: 'TxReceipt' } as any as TxReceipt; const mockViewResultValue = 1; const l1Addresses: L1ContractAddresses = { + availabilityOracleAddress: EthAddress.random(), rollupAddress: EthAddress.random(), registryAddress: EthAddress.random(), inboxAddress: EthAddress.random(), diff --git a/yarn-project/cli/src/utils.ts b/yarn-project/cli/src/utils.ts index 6745c533194e..a3926ae67502 100644 --- a/yarn-project/cli/src/utils.ts +++ b/yarn-project/cli/src/utils.ts @@ -4,6 +4,7 @@ import { type L1ContractArtifactsForDeployment } from '@aztec/aztec.js/ethereum' import { type PXE } from '@aztec/aztec.js/interfaces/pxe'; import { DebugLogger, LogFn } from '@aztec/foundation/log'; import { NoirPackageConfig } from '@aztec/foundation/noir'; +import { AvailabilityOracleAbi, AvailabilityOracleBytecode } from '@aztec/l1-artifacts'; import TOML from '@iarna/toml'; import { CommanderError, InvalidArgumentError } from 'commander'; @@ -80,6 +81,10 @@ export async function deployAztecContracts( contractAbi: OutboxAbi, contractBytecode: OutboxBytecode, }, + availabilityOracle: { + contractAbi: AvailabilityOracleAbi, + contractBytecode: AvailabilityOracleBytecode, + }, rollup: { contractAbi: RollupAbi, contractBytecode: RollupBytecode, diff --git a/yarn-project/ethereum/src/deploy_l1_contracts.ts b/yarn-project/ethereum/src/deploy_l1_contracts.ts index 319243b3c12d..768cb0fa20f9 100644 --- a/yarn-project/ethereum/src/deploy_l1_contracts.ts +++ b/yarn-project/ethereum/src/deploy_l1_contracts.ts @@ -68,6 +68,10 @@ export interface L1ContractArtifactsForDeployment { * Outbox contract artifacts */ outbox: ContractArtifacts; + /** + * Availability Oracle contract artifacts + */ + availabilityOracle: ContractArtifacts; /** * Registry contract artifacts */ @@ -132,6 +136,14 @@ export const deployL1Contracts = async ( ); logger(`Deployed Outbox at ${outboxAddress}`); + const availabilityOracleAddress = await deployL1Contract( + walletClient, + publicClient, + contractsToDeploy.availabilityOracle.contractAbi, + contractsToDeploy.availabilityOracle.contractBytecode, + ); + logger(`Deployed AvailabilityOracle at ${availabilityOracleAddress}`); + const rollupAddress = await deployL1Contract( walletClient, publicClient, @@ -162,6 +174,7 @@ export const deployL1Contracts = async ( logger(`Deployed contract deployment emitter at ${contractDeploymentEmitterAddress}`); const l1Contracts: L1ContractAddresses = { + availabilityOracleAddress, rollupAddress, registryAddress, inboxAddress, diff --git a/yarn-project/ethereum/src/l1_contract_addresses.ts b/yarn-project/ethereum/src/l1_contract_addresses.ts index 19fdc4a4e0b6..272faccb370d 100644 --- a/yarn-project/ethereum/src/l1_contract_addresses.ts +++ b/yarn-project/ethereum/src/l1_contract_addresses.ts @@ -4,6 +4,10 @@ import { EthAddress } from '@aztec/foundation/eth-address'; * Provides the directory of current L1 contract addresses */ export interface L1ContractAddresses { + /** + * Availability Oracle Address. + */ + availabilityOracleAddress: EthAddress; /** * Rollup Address. */ diff --git a/yarn-project/l1-artifacts/scripts/generate-artifacts.sh b/yarn-project/l1-artifacts/scripts/generate-artifacts.sh index eae121bdcd31..83112e1fa89f 100755 --- a/yarn-project/l1-artifacts/scripts/generate-artifacts.sh +++ b/yarn-project/l1-artifacts/scripts/generate-artifacts.sh @@ -10,6 +10,7 @@ target_dir=./generated # - a .{CONTRACT_NAME}Abi.ts containing the contract ABI. CONTRACTS=( + "l1-contracts:AvailabilityOracle" "l1-contracts:Registry" "l1-contracts:Inbox" "l1-contracts:Outbox" diff --git a/yarn-project/pxe/src/pxe_service/test/pxe_service.test.ts b/yarn-project/pxe/src/pxe_service/test/pxe_service.test.ts index b365c03f3adf..617fdd3de96a 100644 --- a/yarn-project/pxe/src/pxe_service/test/pxe_service.test.ts +++ b/yarn-project/pxe/src/pxe_service/test/pxe_service.test.ts @@ -25,6 +25,7 @@ async function createPXEService(): Promise { node.getVersion.mockResolvedValue(1); node.getChainId.mockResolvedValue(1); const mockedContracts: L1ContractAddresses = { + availabilityOracleAddress: EthAddress.random(), rollupAddress: EthAddress.random(), registryAddress: EthAddress.random(), inboxAddress: EthAddress.random(), diff --git a/yarn-project/sequencer-client/src/config.ts b/yarn-project/sequencer-client/src/config.ts index bccbe1e62314..ee407d8410a9 100644 --- a/yarn-project/sequencer-client/src/config.ts +++ b/yarn-project/sequencer-client/src/config.ts @@ -39,6 +39,7 @@ export function getConfigEnvVars(): SequencerClientConfig { SEQ_TX_POLLING_INTERVAL_MS, SEQ_MAX_TX_PER_BLOCK, SEQ_MIN_TX_PER_BLOCK, + AVAILABILITY_ORACLE_CONTRACT_ADDRESS, ROLLUP_CONTRACT_ADDRESS, REGISTRY_CONTRACT_ADDRESS, INBOX_CONTRACT_ADDRESS, @@ -51,6 +52,9 @@ export function getConfigEnvVars(): SequencerClientConfig { : NULL_KEY; // Populate the relevant addresses for use by the sequencer const addresses: L1ContractAddresses = { + availabilityOracleAddress: AVAILABILITY_ORACLE_CONTRACT_ADDRESS + ? EthAddress.fromString(AVAILABILITY_ORACLE_CONTRACT_ADDRESS) + : EthAddress.ZERO, rollupAddress: ROLLUP_CONTRACT_ADDRESS ? EthAddress.fromString(ROLLUP_CONTRACT_ADDRESS) : EthAddress.ZERO, registryAddress: REGISTRY_CONTRACT_ADDRESS ? EthAddress.fromString(REGISTRY_CONTRACT_ADDRESS) : EthAddress.ZERO, inboxAddress: INBOX_CONTRACT_ADDRESS ? EthAddress.fromString(INBOX_CONTRACT_ADDRESS) : EthAddress.ZERO, diff --git a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts index 1ddd02c92749..d192810e8390 100644 --- a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts +++ b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts @@ -38,6 +38,13 @@ export type MinimalTransactionReceipt = { * Pushes txs to the L1 chain and waits for their completion. */ export interface L1PublisherTxSender { + /** + * Publishes block body to Data Availability Oracle. + * @param encodedBody - Encoded block body. + * @returns The hash of the mined tx. + */ + sendPublishBodyTx(encodedBody: Buffer): Promise; + /** * Sends a tx to the L1 rollup contract with a new L2 block. Returns once the tx has been mined. * @param encodedData - Serialized data for processing the new L2 block. @@ -79,6 +86,13 @@ export interface L1PublisherTxSender { * @returns The current archive root of the rollup contract. */ getCurrentArchive(): Promise; + + /** + * Checks if the body of the given block has been published to availability oracle.. + * @param block - The block of which to check whether body has been published. + * @returns True if the body has been published, false otherwise. + */ + checkIfBodyPublished(block: L2Block): Promise; } /** @@ -131,23 +145,50 @@ export class L1Publisher implements L2BlockReceiver { * @returns True once the tx has been confirmed and is successful, false on revert or interrupt, blocks otherwise. */ public async processL2Block(block: L2Block): Promise { - const txData = { + // TODO: Remove this block number check, it's here because we don't currently have proper genesis state on the contract + const lastArchive = block.header.lastArchive.root.toBuffer(); + if (block.number != 1 && !(await this.checkLastArchiveHash(lastArchive))) { + this.log(`Detected different last archive prior to publishing a block, aborting publish...`); + return false; + } + + const encodedBody = block.bodyToBuffer(); + + while (!this.interrupted) { + if (await this.txSender.checkIfBodyPublished(block)) { + this.log(`Body of a block ${block.number} already published.`); + break; + } + + const txHash = await this.sendPublishBodyTx(encodedBody); + if (!txHash) { + return false; + } + + const receipt = await this.getTransactionReceipt(txHash); + if (!receipt) { + return false; + } + + if (receipt.status) { + this.log.info(`Block body published`); + break; + } + + this.log(`AvailabilityOracle.publish tx status failed: ${receipt.transactionHash}`); + await this.sleepOrInterrupted(); + } + + const processTxArgs = { header: block.header.toBuffer(), archive: block.archive.root.toBuffer(), txsHash: block.getCalldataHash(), - body: block.bodyToBuffer(), + body: encodedBody, proof: Buffer.alloc(0), }; - const lastArchive = block.header.lastArchive.root.toBuffer(); while (!this.interrupted) { - // TODO: Remove this block number check, it's here because we don't currently have proper genesis state on the contract - if (block.number != 1 && !(await this.checkLastArchiveHash(lastArchive))) { - this.log(`Detected different last archive prior to publishing a block, aborting publish...`); - break; - } - - const txHash = await this.sendProcessTx(txData); + const txHash = await this.sendProcessTx(processTxArgs); if (!txHash) { break; } @@ -172,11 +213,11 @@ export class L1Publisher implements L2BlockReceiver { // Check if someone else incremented the block number if (!(await this.checkLastArchiveHash(lastArchive))) { - this.log('Publish failed. Detected different state hash.'); + this.log('Publish failed. Detected different last archive hash.'); break; } - this.log(`Transaction status failed: ${receipt.transactionHash}`); + this.log(`Rollup.process tx status failed: ${receipt.transactionHash}`); await this.sleepOrInterrupted(); } @@ -258,6 +299,17 @@ export class L1Publisher implements L2BlockReceiver { return areSame; } + private async sendPublishBodyTx(encodedBody: Buffer): Promise { + while (!this.interrupted) { + try { + return await this.txSender.sendPublishBodyTx(encodedBody); + } catch (err) { + this.log.error(`Block body publish failed`, err); + return undefined; + } + } + } + private async sendProcessTx(encodedData: L1ProcessArgs): Promise { while (!this.interrupted) { try { diff --git a/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts b/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts index c592393118b3..e72f621e0470 100644 --- a/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts +++ b/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts @@ -1,7 +1,7 @@ import { BLOB_SIZE_IN_BYTES, ExtendedContractData } from '@aztec/circuit-types'; import { createEthereumChain } from '@aztec/ethereum'; import { createDebugLogger } from '@aztec/foundation/log'; -import { ContractDeploymentEmitterAbi, RollupAbi } from '@aztec/l1-artifacts'; +import { AvailabilityOracleAbi, ContractDeploymentEmitterAbi, RollupAbi } from '@aztec/l1-artifacts'; import { GetContractReturnType, @@ -31,6 +31,11 @@ import { * Pushes transactions to the L1 rollup contract using viem. */ export class ViemTxSender implements L1PublisherTxSender { + private availabilityOracleContract: GetContractReturnType< + typeof AvailabilityOracleAbi, + PublicClient, + WalletClient + >; private rollupContract: GetContractReturnType< typeof RollupAbi, PublicClient, @@ -61,6 +66,12 @@ export class ViemTxSender implements L1PublisherTxSender { transport: http(chain.rpcUrl), }); + this.availabilityOracleContract = getContract({ + address: getAddress(l1Contracts.availabilityOracleAddress.toString()), + abi: AvailabilityOracleAbi, + publicClient: this.publicClient, + walletClient, + }); this.rollupContract = getContract({ address: getAddress(l1Contracts.rollupAddress.toString()), abi: RollupAbi, @@ -116,6 +127,24 @@ export class ViemTxSender implements L1PublisherTxSender { return undefined; } + /** + * Publishes block body to Data Availability Oracle. + * @param encodedBody - Encoded block body. + * @returns The hash of the mined tx. + */ + async sendPublishBodyTx(encodedBody: Buffer): Promise { + const args = [`0x${encodedBody.toString('hex')}`] as const; + + const gas = await this.availabilityOracleContract.estimateGas.publish(args, { + account: this.account, + }); + const hash = await this.availabilityOracleContract.write.publish(args, { + gas, + account: this.account, + }); + return hash; + } + /** * Sends a tx to the L1 rollup contract with a new L2 block. Returns once the tx has been mined. * @param encodedData - Serialized data for processing the new L2 block. From 71563ed3ebaa148a6279ae599ddd5c0f1d4f17d2 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 18 Jan 2024 10:51:22 +0000 Subject: [PATCH 04/22] WIP --- yarn-project/aztec-sandbox/src/sandbox.ts | 6 ++++++ yarn-project/end-to-end/src/fixtures/utils.ts | 6 ++++++ .../sequencer-client/src/publisher/l1-publisher.ts | 8 ++++---- .../sequencer-client/src/publisher/viem-tx-sender.ts | 7 ++++++- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/yarn-project/aztec-sandbox/src/sandbox.ts b/yarn-project/aztec-sandbox/src/sandbox.ts index a268904da116..acb868e4bca4 100644 --- a/yarn-project/aztec-sandbox/src/sandbox.ts +++ b/yarn-project/aztec-sandbox/src/sandbox.ts @@ -11,6 +11,8 @@ import { import { createDebugLogger } from '@aztec/foundation/log'; import { retryUntil } from '@aztec/foundation/retry'; import { + AvailabilityOracleAbi, + AvailabilityOracleBytecode, ContractDeploymentEmitterAbi, ContractDeploymentEmitterBytecode, InboxAbi, @@ -90,6 +92,10 @@ export async function deployContractsToL1(aztecNodeConfig: AztecNodeConfig, hdAc contractAbi: OutboxAbi, contractBytecode: OutboxBytecode, }, + availabilityOracle: { + contractAbi: AvailabilityOracleAbi, + contractBytecode: AvailabilityOracleBytecode, + }, rollup: { contractAbi: RollupAbi, contractBytecode: RollupBytecode, diff --git a/yarn-project/end-to-end/src/fixtures/utils.ts b/yarn-project/end-to-end/src/fixtures/utils.ts index eb79f56f9a95..2983250a73c8 100644 --- a/yarn-project/end-to-end/src/fixtures/utils.ts +++ b/yarn-project/end-to-end/src/fixtures/utils.ts @@ -20,6 +20,8 @@ import { waitForPXE, } from '@aztec/aztec.js'; import { + AvailabilityOracleAbi, + AvailabilityOracleBytecode, ContractDeploymentEmitterAbi, ContractDeploymentEmitterBytecode, InboxAbi, @@ -87,6 +89,10 @@ export const setupL1Contracts = async ( contractAbi: OutboxAbi, contractBytecode: OutboxBytecode, }, + availabilityOracle: { + contractAbi: AvailabilityOracleAbi, + contractBytecode: AvailabilityOracleBytecode, + }, rollup: { contractAbi: RollupAbi, contractBytecode: RollupBytecode, diff --git a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts index d192810e8390..d06ad2c6123d 100644 --- a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts +++ b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts @@ -88,11 +88,11 @@ export interface L1PublisherTxSender { getCurrentArchive(): Promise; /** - * Checks if the body of the given block has been published to availability oracle.. + * Checks if the body of the given block has been is available. * @param block - The block of which to check whether body has been published. - * @returns True if the body has been published, false otherwise. + * @returns True if the body is available, false otherwise. */ - checkIfBodyPublished(block: L2Block): Promise; + checkIfBodyIsAvailable(block: L2Block): Promise; } /** @@ -155,7 +155,7 @@ export class L1Publisher implements L2BlockReceiver { const encodedBody = block.bodyToBuffer(); while (!this.interrupted) { - if (await this.txSender.checkIfBodyPublished(block)) { + if (await this.txSender.checkIfBodyIsAvailable(block)) { this.log(`Body of a block ${block.number} already published.`); break; } diff --git a/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts b/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts index e72f621e0470..7144f0f9d805 100644 --- a/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts +++ b/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts @@ -1,4 +1,4 @@ -import { BLOB_SIZE_IN_BYTES, ExtendedContractData } from '@aztec/circuit-types'; +import { BLOB_SIZE_IN_BYTES, ExtendedContractData, L2Block } from '@aztec/circuit-types'; import { createEthereumChain } from '@aztec/ethereum'; import { createDebugLogger } from '@aztec/foundation/log'; import { AvailabilityOracleAbi, ContractDeploymentEmitterAbi, RollupAbi } from '@aztec/l1-artifacts'; @@ -91,6 +91,11 @@ export class ViemTxSender implements L1PublisherTxSender { return Buffer.from(archive.replace('0x', ''), 'hex'); } + checkIfBodyIsAvailable(block: L2Block): Promise { + const args = [`0x${block.getCalldataHash().toString('hex')}`] as const; + return this.availabilityOracleContract.read.isAvailable(args); + } + async getTransactionStats(txHash: string): Promise { const tx = await this.publicClient.getTransaction({ hash: txHash as Hex }); if (!tx) { From 168ad81893501e3749c51b306c4e20a68959e22b Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 18 Jan 2024 11:41:53 +0000 Subject: [PATCH 05/22] WIP --- .../src/core/availability_oracle/AvailabilityOracle.sol | 3 +++ l1-contracts/src/core/interfaces/IAvailabilityOracle.sol | 2 ++ 2 files changed, 5 insertions(+) diff --git a/l1-contracts/src/core/availability_oracle/AvailabilityOracle.sol b/l1-contracts/src/core/availability_oracle/AvailabilityOracle.sol index 0f4041d16d25..70bf9a32c48d 100644 --- a/l1-contracts/src/core/availability_oracle/AvailabilityOracle.sol +++ b/l1-contracts/src/core/availability_oracle/AvailabilityOracle.sol @@ -24,6 +24,9 @@ contract AvailabilityOracle is IAvailabilityOracle { function publish(bytes calldata _body) external override(IAvailabilityOracle) returns (bytes32) { bytes32 _txsHash = TxsDecoder.decode(_body); isAvailable[_txsHash] = true; + + emit BodyPublished(_txsHash); + return _txsHash; } } diff --git a/l1-contracts/src/core/interfaces/IAvailabilityOracle.sol b/l1-contracts/src/core/interfaces/IAvailabilityOracle.sol index 302f6dbc0e5d..00649ac0e910 100644 --- a/l1-contracts/src/core/interfaces/IAvailabilityOracle.sol +++ b/l1-contracts/src/core/interfaces/IAvailabilityOracle.sol @@ -3,6 +3,8 @@ pragma solidity >=0.8.18; interface IAvailabilityOracle { + event BodyPublished(bytes32 indexed txsHash); + function publish(bytes calldata _body) external returns (bytes32); function isAvailable(bytes32 _txsHash) external view returns (bool); From d65e594af7b95b3f609789b6501fb18b47c5013d Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 18 Jan 2024 12:43:51 +0000 Subject: [PATCH 06/22] displaying txsHash in log message --- .../core/interfaces/IAvailabilityOracle.sol | 2 +- .../src/publisher/l1-publisher.ts | 18 +++++++++++++++--- .../src/publisher/viem-tx-sender.ts | 1 + 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/l1-contracts/src/core/interfaces/IAvailabilityOracle.sol b/l1-contracts/src/core/interfaces/IAvailabilityOracle.sol index 00649ac0e910..0a3b4cc80662 100644 --- a/l1-contracts/src/core/interfaces/IAvailabilityOracle.sol +++ b/l1-contracts/src/core/interfaces/IAvailabilityOracle.sol @@ -3,7 +3,7 @@ pragma solidity >=0.8.18; interface IAvailabilityOracle { - event BodyPublished(bytes32 indexed txsHash); + event BodyPublished(bytes32 txsHash); function publish(bytes calldata _body) external returns (bytes32); diff --git a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts index d06ad2c6123d..0ed2d67813a9 100644 --- a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts +++ b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts @@ -28,10 +28,12 @@ export type MinimalTransactionReceipt = { status: boolean; /** Hash of the transaction. */ transactionHash: string; - /** Effective gas used by the tx */ + /** Effective gas used by the tx. */ gasUsed: bigint; - /** Effective gas price paid by the tx */ + /** Effective gas price paid by the tx. */ gasPrice: bigint; + /** Logs emitted in this tx. */ + logs: any[]; }; /** @@ -154,6 +156,7 @@ export class L1Publisher implements L2BlockReceiver { const encodedBody = block.bodyToBuffer(); + // Publish block body while (!this.interrupted) { if (await this.txSender.checkIfBodyIsAvailable(block)) { this.log(`Body of a block ${block.number} already published.`); @@ -171,7 +174,15 @@ export class L1Publisher implements L2BlockReceiver { } if (receipt.status) { - this.log.info(`Block body published`); + let txsHash; + if (receipt.logs.length === 1) { + // txsHash from IAvailabilityOracle.BlockPublished event + txsHash = receipt.logs[0].data; + } else { + this.log(`Expected 1 log, got ${receipt.logs.length}`); + } + + this.log.info(`Block body published, txsHash: ${txsHash}`); break; } @@ -187,6 +198,7 @@ export class L1Publisher implements L2BlockReceiver { proof: Buffer.alloc(0), }; + // Process block while (!this.interrupted) { const txHash = await this.sendProcessTx(processTxArgs); if (!txHash) { diff --git a/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts b/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts index 7144f0f9d805..6686371c56aa 100644 --- a/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts +++ b/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts @@ -125,6 +125,7 @@ export class ViemTxSender implements L1PublisherTxSender { transactionHash: txHash, gasUsed: receipt.gasUsed, gasPrice: receipt.effectiveGasPrice, + logs: receipt.logs, }; } From 6dfb065ee5665da7acc06044dce7539e28226be8 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 18 Jan 2024 13:00:02 +0000 Subject: [PATCH 07/22] WIP --- l1-contracts/src/core/Rollup.sol | 1 - .../AvailabilityOracle.sol | 4 +-- .../core/interfaces/IAvailabilityOracle.sol | 2 +- .../src/publisher/l1-publisher.ts | 30 +++++++++---------- .../src/publisher/viem-tx-sender.ts | 6 ++-- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/l1-contracts/src/core/Rollup.sol b/l1-contracts/src/core/Rollup.sol index 51911d0b7e3c..588c8693c7dd 100644 --- a/l1-contracts/src/core/Rollup.sol +++ b/l1-contracts/src/core/Rollup.sol @@ -64,7 +64,6 @@ contract Rollup is IRollup { // Check if the data is available using availability oracle (change availability oracle if you want a different DA layer) if (!AVAILABILITY_ORACLE.isAvailable(_txsHash)) { - // @todo @LHerskind Impossible to hit with above hack. revert Errors.Rollup__UnavailableTxs(_txsHash); } diff --git a/l1-contracts/src/core/availability_oracle/AvailabilityOracle.sol b/l1-contracts/src/core/availability_oracle/AvailabilityOracle.sol index 70bf9a32c48d..7695e508807a 100644 --- a/l1-contracts/src/core/availability_oracle/AvailabilityOracle.sol +++ b/l1-contracts/src/core/availability_oracle/AvailabilityOracle.sol @@ -18,14 +18,14 @@ contract AvailabilityOracle is IAvailabilityOracle { /** * @notice Publishes transactions and marks its commitment, the TxsHash, as available - * @param _body - The L1 calldata + * @param _body - The block body * @return txsHash - The TxsHash */ function publish(bytes calldata _body) external override(IAvailabilityOracle) returns (bytes32) { bytes32 _txsHash = TxsDecoder.decode(_body); isAvailable[_txsHash] = true; - emit BodyPublished(_txsHash); + emit TxsPublished(_txsHash); return _txsHash; } diff --git a/l1-contracts/src/core/interfaces/IAvailabilityOracle.sol b/l1-contracts/src/core/interfaces/IAvailabilityOracle.sol index 0a3b4cc80662..38f5176596c9 100644 --- a/l1-contracts/src/core/interfaces/IAvailabilityOracle.sol +++ b/l1-contracts/src/core/interfaces/IAvailabilityOracle.sol @@ -3,7 +3,7 @@ pragma solidity >=0.8.18; interface IAvailabilityOracle { - event BodyPublished(bytes32 txsHash); + event TxsPublished(bytes32 txsHash); function publish(bytes calldata _body) external returns (bytes32); diff --git a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts index 0ed2d67813a9..63294c11c9a6 100644 --- a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts +++ b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts @@ -41,11 +41,11 @@ export type MinimalTransactionReceipt = { */ export interface L1PublisherTxSender { /** - * Publishes block body to Data Availability Oracle. + * Publishes tx effects to Availability Oracle. * @param encodedBody - Encoded block body. * @returns The hash of the mined tx. */ - sendPublishBodyTx(encodedBody: Buffer): Promise; + sendPublishTx(encodedBody: Buffer): Promise; /** * Sends a tx to the L1 rollup contract with a new L2 block. Returns once the tx has been mined. @@ -90,11 +90,11 @@ export interface L1PublisherTxSender { getCurrentArchive(): Promise; /** - * Checks if the body of the given block has been is available. - * @param block - The block of which to check whether body has been published. - * @returns True if the body is available, false otherwise. + * Checks if the transaction effects of the given block is available. + * @param block - The block of which to check whether txs are available. + * @returns True if the txs are available, false otherwise. */ - checkIfBodyIsAvailable(block: L2Block): Promise; + checkIfTxsAreAvailable(block: L2Block): Promise; } /** @@ -156,14 +156,14 @@ export class L1Publisher implements L2BlockReceiver { const encodedBody = block.bodyToBuffer(); - // Publish block body + // Publish block transaction effects while (!this.interrupted) { - if (await this.txSender.checkIfBodyIsAvailable(block)) { - this.log(`Body of a block ${block.number} already published.`); + if (await this.txSender.checkIfTxsAreAvailable(block)) { + this.log(`Transaction effects of a block ${block.number} already published.`); break; } - const txHash = await this.sendPublishBodyTx(encodedBody); + const txHash = await this.sendPublishTx(encodedBody); if (!txHash) { return false; } @@ -176,13 +176,13 @@ export class L1Publisher implements L2BlockReceiver { if (receipt.status) { let txsHash; if (receipt.logs.length === 1) { - // txsHash from IAvailabilityOracle.BlockPublished event + // txsHash from IAvailabilityOracle.TxsPublished event txsHash = receipt.logs[0].data; } else { this.log(`Expected 1 log, got ${receipt.logs.length}`); } - this.log.info(`Block body published, txsHash: ${txsHash}`); + this.log.info(`Block txs effects published, txsHash: ${txsHash}`); break; } @@ -311,12 +311,12 @@ export class L1Publisher implements L2BlockReceiver { return areSame; } - private async sendPublishBodyTx(encodedBody: Buffer): Promise { + private async sendPublishTx(encodedBody: Buffer): Promise { while (!this.interrupted) { try { - return await this.txSender.sendPublishBodyTx(encodedBody); + return await this.txSender.sendPublishTx(encodedBody); } catch (err) { - this.log.error(`Block body publish failed`, err); + this.log.error(`TxEffects publish failed`, err); return undefined; } } diff --git a/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts b/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts index 6686371c56aa..33911815709a 100644 --- a/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts +++ b/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts @@ -91,7 +91,7 @@ export class ViemTxSender implements L1PublisherTxSender { return Buffer.from(archive.replace('0x', ''), 'hex'); } - checkIfBodyIsAvailable(block: L2Block): Promise { + checkIfTxsAreAvailable(block: L2Block): Promise { const args = [`0x${block.getCalldataHash().toString('hex')}`] as const; return this.availabilityOracleContract.read.isAvailable(args); } @@ -134,11 +134,11 @@ export class ViemTxSender implements L1PublisherTxSender { } /** - * Publishes block body to Data Availability Oracle. + * Publishes tx effects to Availability Oracle. * @param encodedBody - Encoded block body. * @returns The hash of the mined tx. */ - async sendPublishBodyTx(encodedBody: Buffer): Promise { + async sendPublishTx(encodedBody: Buffer): Promise { const args = [`0x${encodedBody.toString('hex')}`] as const; const gas = await this.availabilityOracleContract.estimateGas.publish(args, { From 2fd5f9b004e0633cc50bb103f36d206b75ff6ac0 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 18 Jan 2024 13:26:27 +0000 Subject: [PATCH 08/22] AvailabilityOracle in Registry --- l1-contracts/src/core/Rollup.sol | 5 +---- .../core/interfaces/messagebridge/IRegistry.sol | 7 ++++++- .../src/core/libraries/DataStructures.sol | 2 ++ l1-contracts/src/core/messagebridge/Registry.sol | 16 +++++++++++++--- l1-contracts/test/Inbox.t.sol | 4 ++-- l1-contracts/test/Outbox.t.sol | 5 +++-- l1-contracts/test/Registry.t.sol | 7 ++++--- l1-contracts/test/Rollup.t.sol | 4 ++-- l1-contracts/test/portals/TokenPortal.t.sol | 5 ++++- l1-contracts/test/portals/UniswapPortal.t.sol | 5 ++++- yarn-project/ethereum/src/deploy_l1_contracts.ts | 7 ++++++- 11 files changed, 47 insertions(+), 20 deletions(-) diff --git a/l1-contracts/src/core/Rollup.sol b/l1-contracts/src/core/Rollup.sol index 588c8693c7dd..50c2c978bb3a 100644 --- a/l1-contracts/src/core/Rollup.sol +++ b/l1-contracts/src/core/Rollup.sol @@ -16,7 +16,6 @@ import {Errors} from "./libraries/Errors.sol"; // Contracts import {MockVerifier} from "../mock/MockVerifier.sol"; -import {AvailabilityOracle} from "./availability_oracle/AvailabilityOracle.sol"; /** * @title Rollup @@ -28,7 +27,6 @@ contract Rollup is IRollup { MockVerifier public immutable VERIFIER; IRegistry public immutable REGISTRY; uint256 public immutable VERSION; - AvailabilityOracle public immutable AVAILABILITY_ORACLE; bytes32 public archive; // Root of the archive tree uint256 public lastBlockTs; @@ -38,7 +36,6 @@ contract Rollup is IRollup { constructor(IRegistry _registry) { VERIFIER = new MockVerifier(); - AVAILABILITY_ORACLE = new AvailabilityOracle(); REGISTRY = _registry; VERSION = 1; } @@ -63,7 +60,7 @@ contract Rollup is IRollup { HeaderLib.validate(header, VERSION, lastBlockTs, archive); // Check if the data is available using availability oracle (change availability oracle if you want a different DA layer) - if (!AVAILABILITY_ORACLE.isAvailable(_txsHash)) { + if (!REGISTRY.getAvailabilityOracle().isAvailable(_txsHash)) { revert Errors.Rollup__UnavailableTxs(_txsHash); } diff --git a/l1-contracts/src/core/interfaces/messagebridge/IRegistry.sol b/l1-contracts/src/core/interfaces/messagebridge/IRegistry.sol index 0d184a521f21..426dcdf3a474 100644 --- a/l1-contracts/src/core/interfaces/messagebridge/IRegistry.sol +++ b/l1-contracts/src/core/interfaces/messagebridge/IRegistry.sol @@ -5,10 +5,13 @@ import {DataStructures} from "../../libraries/DataStructures.sol"; import {IRollup} from "../IRollup.sol"; import {IInbox} from "./IInbox.sol"; import {IOutbox} from "./IOutbox.sol"; +import {IAvailabilityOracle} from "../../interfaces/IAvailabilityOracle.sol"; interface IRegistry { // docs:start:registry_upgrade - function upgrade(address _rollup, address _inbox, address _outbox) external returns (uint256); + function upgrade(address _rollup, address _inbox, address _outbox, address _availabilityOracle) + external + returns (uint256); // docs:end:registry_upgrade // docs:start:registry_get_rollup @@ -27,6 +30,8 @@ interface IRegistry { function getOutbox() external view returns (IOutbox); // docs:end:registry_get_outbox + function getAvailabilityOracle() external view returns (IAvailabilityOracle); + // docs:start:registry_get_snapshot function getSnapshot(uint256 _version) external diff --git a/l1-contracts/src/core/libraries/DataStructures.sol b/l1-contracts/src/core/libraries/DataStructures.sol index f588c7c1d4d6..465e0bf11f8a 100644 --- a/l1-contracts/src/core/libraries/DataStructures.sol +++ b/l1-contracts/src/core/libraries/DataStructures.sol @@ -88,12 +88,14 @@ library DataStructures { * @param rollup - The address of the rollup contract * @param inbox - The address of the inbox contract * @param outbox - The address of the outbox contract + * @param availabilityOracle - The address of the availability oracle contract * @param blockNumber - The block number of the snapshot */ struct RegistrySnapshot { address rollup; address inbox; address outbox; + address availabilityOracle; uint256 blockNumber; } // docs:end:registry_snapshot diff --git a/l1-contracts/src/core/messagebridge/Registry.sol b/l1-contracts/src/core/messagebridge/Registry.sol index 947597c8b02f..73de83fbb604 100644 --- a/l1-contracts/src/core/messagebridge/Registry.sol +++ b/l1-contracts/src/core/messagebridge/Registry.sol @@ -7,6 +7,7 @@ import {IRegistry} from "../interfaces/messagebridge/IRegistry.sol"; import {IRollup} from "../interfaces/IRollup.sol"; import {IInbox} from "../interfaces/messagebridge/IInbox.sol"; import {IOutbox} from "../interfaces/messagebridge/IOutbox.sol"; +import {IAvailabilityOracle} from "../interfaces/IAvailabilityOracle.sol"; // Libraries import {DataStructures} from "../libraries/DataStructures.sol"; @@ -29,7 +30,7 @@ contract Registry is IRegistry { constructor() { // Inserts a "dead" rollup and message boxes at version 0 // This is simply done to make first version 1, which fits better with the rest of the system - upgrade(address(0xdead), address(0xdead), address(0xdead)); + upgrade(address(0xdead), address(0xdead), address(0xdead), address(0xdead)); } /** @@ -67,6 +68,14 @@ contract Registry is IRegistry { return IOutbox(currentSnapshot.outbox); } + /** + * @notice Returns the availability oracle contract + * @return The availability oracle contract (of type IAvailabilityOracle) + */ + function getAvailabilityOracle() external view override(IRegistry) returns (IAvailabilityOracle) { + return IAvailabilityOracle(currentSnapshot.availabilityOracle); + } + /** * @notice Fetches a snapshot of the registry indicated by `version` * @dev the version is 0 indexed, so the first snapshot is version 0. @@ -102,9 +111,10 @@ contract Registry is IRegistry { * @param _rollup - The address of the rollup contract * @param _inbox - The address of the inbox contract * @param _outbox - The address of the outbox contract + * @param _availabilityOracle - The address of the availability oracle contract * @return The version of the new snapshot */ - function upgrade(address _rollup, address _inbox, address _outbox) + function upgrade(address _rollup, address _inbox, address _outbox, address _availabilityOracle) public override(IRegistry) returns (uint256) @@ -113,7 +123,7 @@ contract Registry is IRegistry { if (exists) revert Errors.Registry__RollupAlreadyRegistered(_rollup); DataStructures.RegistrySnapshot memory newSnapshot = - DataStructures.RegistrySnapshot(_rollup, _inbox, _outbox, block.number); + DataStructures.RegistrySnapshot(_rollup, _inbox, _outbox, _availabilityOracle, block.number); currentSnapshot = newSnapshot; uint256 version = numberOfVersions++; snapshots[version] = newSnapshot; diff --git a/l1-contracts/test/Inbox.t.sol b/l1-contracts/test/Inbox.t.sol index a120aa0bb394..57b1a0df8d1c 100644 --- a/l1-contracts/test/Inbox.t.sol +++ b/l1-contracts/test/Inbox.t.sol @@ -35,7 +35,7 @@ contract InboxTest is Test { address rollup = address(this); registry = new Registry(); inbox = new Inbox(address(registry)); - version = registry.upgrade(rollup, address(inbox), address(0x0)); + version = registry.upgrade(rollup, address(inbox), address(0x0), address(0x0)); } function _fakeMessage() internal view returns (DataStructures.L1ToL2Msg memory) { @@ -254,7 +254,7 @@ contract InboxTest is Test { function testRevertIfConsumingFromWrongRollup() public { address wrongRollup = address(0xbeeffeed); - uint256 wrongVersion = registry.upgrade(wrongRollup, address(inbox), address(0x0)); + uint256 wrongVersion = registry.upgrade(wrongRollup, address(inbox), address(0x0), address(0x0)); DataStructures.L1ToL2Msg memory message = _fakeMessage(); address feeCollector = address(0x1); diff --git a/l1-contracts/test/Outbox.t.sol b/l1-contracts/test/Outbox.t.sol index 4ad45b5abc3f..cecc5d02c045 100644 --- a/l1-contracts/test/Outbox.t.sol +++ b/l1-contracts/test/Outbox.t.sol @@ -22,7 +22,7 @@ contract OutboxTest is Test { address rollup = address(this); registry = new Registry(); outbox = new Outbox(address(registry)); - version = registry.upgrade(rollup, address(0x0), address(outbox)); + version = registry.upgrade(rollup, address(0x0), address(outbox), address(0x0)); } function _fakeMessage() internal view returns (DataStructures.L2ToL1Msg memory) { @@ -89,7 +89,8 @@ contract OutboxTest is Test { function testRevertIfInsertingFromWrongRollup() public { address wrongRollup = address(0xbeeffeed); - uint256 wrongVersion = registry.upgrade(wrongRollup, address(0x0), address(outbox)); + uint256 wrongVersion = + registry.upgrade(wrongRollup, address(0x0), address(outbox), address(0x0)); DataStructures.L2ToL1Msg memory message = _fakeMessage(); // correctly set message.recipient to this address diff --git a/l1-contracts/test/Registry.t.sol b/l1-contracts/test/Registry.t.sol index 6d844c478aff..6ee8f2e76c99 100644 --- a/l1-contracts/test/Registry.t.sol +++ b/l1-contracts/test/Registry.t.sol @@ -38,7 +38,8 @@ contract RegistryTest is Test { address newRollup = address(0xbeef1); address newInbox = address(0xbeef2); address newOutbox = address(0xbeef3); - uint256 newVersion = registry.upgrade(newRollup, newInbox, newOutbox); + address newAvailabilityOracle = address(0xbeef4); + uint256 newVersion = registry.upgrade(newRollup, newInbox, newOutbox, newAvailabilityOracle); assertEq(registry.numberOfVersions(), 2, "should have 2 versions"); DataStructures.RegistrySnapshot memory snapshot = registry.getCurrentSnapshot(); @@ -55,9 +56,9 @@ contract RegistryTest is Test { } function testRevertUpgradeToSame() public { - registry.upgrade(DEAD, DEAD, DEAD); + registry.upgrade(DEAD, DEAD, DEAD, DEAD); vm.expectRevert(abi.encodeWithSelector(Errors.Registry__RollupAlreadyRegistered.selector, DEAD)); - registry.upgrade(DEAD, DEAD, DEAD); + registry.upgrade(DEAD, DEAD, DEAD, DEAD); } function testRevertGetVersionForNonExistent() public { diff --git a/l1-contracts/test/Rollup.t.sol b/l1-contracts/test/Rollup.t.sol index 3d3bd6f6ff2a..7c45d0323749 100644 --- a/l1-contracts/test/Rollup.t.sol +++ b/l1-contracts/test/Rollup.t.sol @@ -37,9 +37,9 @@ contract RollupTest is DecoderBase { inbox = new Inbox(address(registry)); outbox = new Outbox(address(registry)); rollup = new Rollup(registry); - availabilityOracle = rollup.AVAILABILITY_ORACLE(); + availabilityOracle = new AvailabilityOracle(); - registry.upgrade(address(rollup), address(inbox), address(outbox)); + registry.upgrade(address(rollup), address(inbox), address(outbox), address(availabilityOracle)); } function testMixedBlock() public { diff --git a/l1-contracts/test/portals/TokenPortal.t.sol b/l1-contracts/test/portals/TokenPortal.t.sol index ae02336b3df7..0ac38d7e426c 100644 --- a/l1-contracts/test/portals/TokenPortal.t.sol +++ b/l1-contracts/test/portals/TokenPortal.t.sol @@ -7,6 +7,7 @@ import {Rollup} from "../../src/core/Rollup.sol"; import {Inbox} from "../../src/core/messagebridge/Inbox.sol"; import {Registry} from "../../src/core/messagebridge/Registry.sol"; import {Outbox} from "../../src/core/messagebridge/Outbox.sol"; +import {AvailabilityOracle} from "../../src/core/availability_oracle/AvailabilityOracle.sol"; import {DataStructures} from "../../src/core/libraries/DataStructures.sol"; import {Hash} from "../../src/core/libraries/Hash.sol"; import {Errors} from "../../src/core/libraries/Errors.sol"; @@ -38,6 +39,7 @@ contract TokenPortalTest is Test { Inbox internal inbox; Outbox internal outbox; Rollup internal rollup; + AvailabilityOracle internal availabilityOracle; bytes32 internal l2TokenAddress = bytes32(uint256(0x42)); TokenPortal internal tokenPortal; @@ -65,8 +67,9 @@ contract TokenPortalTest is Test { inbox = new Inbox(address(registry)); outbox = new Outbox(address(registry)); rollup = new Rollup(registry); + availabilityOracle = new AvailabilityOracle(); - registry.upgrade(address(rollup), address(inbox), address(outbox)); + registry.upgrade(address(rollup), address(inbox), address(outbox), address(availabilityOracle)); portalERC20 = new PortalERC20(); tokenPortal = new TokenPortal(); diff --git a/l1-contracts/test/portals/UniswapPortal.t.sol b/l1-contracts/test/portals/UniswapPortal.t.sol index 3605e213d03f..df12cf2e4c33 100644 --- a/l1-contracts/test/portals/UniswapPortal.t.sol +++ b/l1-contracts/test/portals/UniswapPortal.t.sol @@ -7,6 +7,7 @@ import {Rollup} from "../../src/core/Rollup.sol"; import {Inbox} from "../../src/core/messagebridge/Inbox.sol"; import {Registry} from "../../src/core/messagebridge/Registry.sol"; import {Outbox} from "../../src/core/messagebridge/Outbox.sol"; +import {AvailabilityOracle} from "../../src/core/availability_oracle/AvailabilityOracle.sol"; import {DataStructures} from "../../src/core/libraries/DataStructures.sol"; import {Hash} from "../../src/core/libraries/Hash.sol"; import {Errors} from "../../src/core/libraries/Errors.sol"; @@ -27,6 +28,7 @@ contract UniswapPortalTest is Test { Inbox internal inbox; Outbox internal outbox; Rollup internal rollup; + AvailabilityOracle internal availabilityOracle; bytes32 internal l2TokenAddress = bytes32(uint256(0x1)); bytes32 internal l2UniswapAddress = bytes32(uint256(0x2)); @@ -52,7 +54,8 @@ contract UniswapPortalTest is Test { inbox = new Inbox(address(registry)); outbox = new Outbox(address(registry)); rollup = new Rollup(registry); - registry.upgrade(address(rollup), address(inbox), address(outbox)); + availabilityOracle = new AvailabilityOracle(); + registry.upgrade(address(rollup), address(inbox), address(outbox), address(availabilityOracle)); daiTokenPortal = new TokenPortal(); daiTokenPortal.initialize(address(registry), address(DAI), l2TokenAddress); diff --git a/yarn-project/ethereum/src/deploy_l1_contracts.ts b/yarn-project/ethereum/src/deploy_l1_contracts.ts index 768cb0fa20f9..a15623d4fd75 100644 --- a/yarn-project/ethereum/src/deploy_l1_contracts.ts +++ b/yarn-project/ethereum/src/deploy_l1_contracts.ts @@ -161,7 +161,12 @@ export const deployL1Contracts = async ( walletClient, }); await registryContract.write.upgrade( - [getAddress(rollupAddress.toString()), getAddress(inboxAddress.toString()), getAddress(outboxAddress.toString())], + [ + getAddress(rollupAddress.toString()), + getAddress(inboxAddress.toString()), + getAddress(outboxAddress.toString()), + getAddress(availabilityOracleAddress.toString()), + ], { account }, ); From bf7e0f647761fc1c28d301686d782cb12ff9165e Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 18 Jan 2024 13:36:45 +0000 Subject: [PATCH 09/22] final touches --- l1-contracts/src/core/Rollup.sol | 2 +- yarn-project/sequencer-client/src/publisher/l1-publisher.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/l1-contracts/src/core/Rollup.sol b/l1-contracts/src/core/Rollup.sol index 50c2c978bb3a..e07079774822 100644 --- a/l1-contracts/src/core/Rollup.sol +++ b/l1-contracts/src/core/Rollup.sol @@ -51,7 +51,7 @@ contract Rollup is IRollup { function process( bytes calldata _header, bytes32 _archive, - bytes32 _txsHash, // TODO(#3938) Update this to be actual txs hash and not the old diff root. + bytes32 _txsHash, // TODO(#3938) Update this to be actual txs hash and not the old block calldata hash. bytes calldata _body, // TODO(#3938) Update this to pass in only th messages and not the whole body. bytes memory _proof ) external override(IRollup) { diff --git a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts index 63294c11c9a6..a69c95c0c55c 100644 --- a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts +++ b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts @@ -90,7 +90,7 @@ export interface L1PublisherTxSender { getCurrentArchive(): Promise; /** - * Checks if the transaction effects of the given block is available. + * Checks if the transaction effects of the given block are available. * @param block - The block of which to check whether txs are available. * @returns True if the txs are available, false otherwise. */ From 9d9a55699d43b61d5ed68e4e86ecef714cbfa7f3 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 18 Jan 2024 13:52:12 +0000 Subject: [PATCH 10/22] fix --- yarn-project/end-to-end/src/fixtures/utils.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/yarn-project/end-to-end/src/fixtures/utils.ts b/yarn-project/end-to-end/src/fixtures/utils.ts index 2983250a73c8..8942bded2971 100644 --- a/yarn-project/end-to-end/src/fixtures/utils.ts +++ b/yarn-project/end-to-end/src/fixtures/utils.ts @@ -285,12 +285,7 @@ export async function setup( opts.deployL1ContractsValues ?? (await setupL1Contracts(config.rpcUrl, hdAccount, logger)); config.publisherPrivateKey = `0x${publisherPrivKey!.toString('hex')}`; - config.l1Contracts.rollupAddress = deployL1ContractsValues.l1ContractAddresses.rollupAddress; - config.l1Contracts.registryAddress = deployL1ContractsValues.l1ContractAddresses.registryAddress; - config.l1Contracts.contractDeploymentEmitterAddress = - deployL1ContractsValues.l1ContractAddresses.contractDeploymentEmitterAddress; - config.l1Contracts.inboxAddress = deployL1ContractsValues.l1ContractAddresses.inboxAddress; - config.l1Contracts.outboxAddress = deployL1ContractsValues.l1ContractAddresses.outboxAddress; + config.l1Contracts = deployL1ContractsValues.l1ContractAddresses; logger('Creating and synching an aztec node...'); const aztecNode = await AztecNodeService.createAndSync(config); From 86428cf51240037ce7c2b45fdee0971ff5136f77 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 18 Jan 2024 14:46:17 +0000 Subject: [PATCH 11/22] fixing l1 publisher test --- .../src/publisher/l1-publisher.test.ts | 87 +++++++++++++++---- 1 file changed, 71 insertions(+), 16 deletions(-) diff --git a/yarn-project/sequencer-client/src/publisher/l1-publisher.test.ts b/yarn-project/sequencer-client/src/publisher/l1-publisher.test.ts index 3ca39d7dd673..493acea85a90 100644 --- a/yarn-project/sequencer-client/src/publisher/l1-publisher.test.ts +++ b/yarn-project/sequencer-client/src/publisher/l1-publisher.test.ts @@ -7,12 +7,15 @@ import { L1Publisher, L1PublisherTxSender, MinimalTransactionReceipt } from './l describe('L1Publisher', () => { let txSender: MockProxy; - let txHash: string; - let txReceipt: MinimalTransactionReceipt; + let publishTxHash: string; + let processTxHash: string; + let processTxReceipt: MinimalTransactionReceipt; + let publishTxReceipt: MinimalTransactionReceipt; let l2Block: L2Block; let header: Buffer; let archive: Buffer; + let txsHash: Buffer; let body: Buffer; let proof: Buffer; @@ -23,14 +26,27 @@ describe('L1Publisher', () => { header = l2Block.header.toBuffer(); archive = l2Block.archive.root.toBuffer(); + txsHash = l2Block.getCalldataHash(); body = l2Block.bodyToBuffer(); proof = Buffer.alloc(0); txSender = mock(); - txHash = `0x${Buffer.from('txHash').toString('hex')}`; // random tx hash - txReceipt = { transactionHash: txHash, status: true } as MinimalTransactionReceipt; - txSender.sendProcessTx.mockResolvedValueOnce(txHash); - txSender.getTransactionReceipt.mockResolvedValueOnce(txReceipt); + + publishTxHash = `0x${Buffer.from('txHashPublish').toString('hex')}`; // random tx hash + processTxHash = `0x${Buffer.from('txHashProcess').toString('hex')}`; // random tx hash + publishTxReceipt = { + transactionHash: publishTxHash, + status: true, + logs: [{ data: txsHash.toString('hex') }], + } as MinimalTransactionReceipt; + processTxReceipt = { + transactionHash: processTxHash, + status: true, + logs: [{ data: '' }], + } as MinimalTransactionReceipt; + txSender.sendPublishTx.mockResolvedValueOnce(processTxHash); + txSender.sendProcessTx.mockResolvedValueOnce(processTxHash); + txSender.getTransactionReceipt.mockResolvedValueOnce(publishTxReceipt).mockResolvedValueOnce(processTxReceipt); txSender.getCurrentArchive.mockResolvedValue(l2Block.header.lastArchive.root.toBuffer()); publisher = new L1Publisher(txSender, { l1BlockPublishRetryIntervalMS: 1 }); @@ -40,45 +56,84 @@ describe('L1Publisher', () => { const result = await publisher.processL2Block(l2Block); expect(result).toEqual(true); - expect(txSender.sendProcessTx).toHaveBeenCalledWith({ header, archive, body, proof }); - expect(txSender.getTransactionReceipt).toHaveBeenCalledWith(txHash); + expect(txSender.sendProcessTx).toHaveBeenCalledWith({ header, archive, txsHash, body, proof }); + expect(txSender.getTransactionReceipt).toHaveBeenCalledWith(processTxHash); }); it('does not publish if last archive root is different to expected', async () => { txSender.getCurrentArchive.mockResolvedValueOnce(L2Block.random(43).archive.root.toBuffer()); const result = await publisher.processL2Block(l2Block); expect(result).toBe(false); + expect(txSender.sendPublishTx).not.toHaveBeenCalled(); expect(txSender.sendProcessTx).not.toHaveBeenCalled(); }); - it('does not retry if sending a tx fails', async () => { - txSender.sendProcessTx.mockReset().mockRejectedValueOnce(new Error()).mockResolvedValueOnce(txHash); + it('does not retry if sending a publish tx fails', async () => { + txSender.sendPublishTx.mockReset().mockRejectedValueOnce(new Error()).mockResolvedValueOnce(processTxHash); const result = await publisher.processL2Block(l2Block); expect(result).toEqual(false); + expect(txSender.sendPublishTx).toHaveBeenCalledTimes(1); + expect(txSender.sendProcessTx).toHaveBeenCalledTimes(0); + }); + + it('does not retry if sending a process tx fails', async () => { + txSender.sendProcessTx.mockReset().mockRejectedValueOnce(new Error()).mockResolvedValueOnce(processTxHash); + + const result = await publisher.processL2Block(l2Block); + + expect(result).toEqual(false); + expect(txSender.sendPublishTx).toHaveBeenCalledTimes(1); expect(txSender.sendProcessTx).toHaveBeenCalledTimes(1); }); it('retries if fetching the receipt fails', async () => { - txSender.getTransactionReceipt.mockReset().mockRejectedValueOnce(new Error()).mockResolvedValueOnce(txReceipt); + txSender.getTransactionReceipt + .mockReset() + .mockRejectedValueOnce(new Error()) + .mockResolvedValueOnce(publishTxReceipt) + .mockRejectedValueOnce(new Error()) + .mockResolvedValueOnce(processTxReceipt); const result = await publisher.processL2Block(l2Block); expect(result).toEqual(true); - expect(txSender.getTransactionReceipt).toHaveBeenCalledTimes(2); + expect(txSender.getTransactionReceipt).toHaveBeenCalledTimes(4); + }); + + it('returns false if publish tx reverts', async () => { + txSender.getTransactionReceipt.mockReset().mockResolvedValueOnce({ ...publishTxReceipt, status: false }); + + const result = await publisher.processL2Block(l2Block); + + expect(result).toEqual(false); }); - it('returns false if tx reverts', async () => { - txSender.getTransactionReceipt.mockReset().mockResolvedValueOnce({ ...txReceipt, status: false }); + it('returns false if process tx reverts', async () => { + txSender.getTransactionReceipt + .mockReset() + .mockResolvedValueOnce(publishTxReceipt) + .mockResolvedValueOnce({ ...publishTxReceipt, status: false }); const result = await publisher.processL2Block(l2Block); expect(result).toEqual(false); }); - it('returns false if interrupted', async () => { - txSender.sendProcessTx.mockReset().mockImplementationOnce(() => sleep(10, txHash)); + it('returns false if sending publish tx is interrupted', async () => { + txSender.sendPublishTx.mockReset().mockImplementationOnce(() => sleep(10, publishTxHash)); + + const resultPromise = publisher.processL2Block(l2Block); + publisher.interrupt(); + const result = await resultPromise; + + expect(result).toEqual(false); + expect(txSender.getTransactionReceipt).not.toHaveBeenCalled(); + }); + + it('returns false if sending process tx is interrupted', async () => { + txSender.sendProcessTx.mockReset().mockImplementationOnce(() => sleep(10, processTxHash)); const resultPromise = publisher.processL2Block(l2Block); publisher.interrupt(); From 19b1eeb879754943d589f4f0174999cf4012c47a Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 19 Jan 2024 08:16:31 +0000 Subject: [PATCH 12/22] publisher test fix --- .../sequencer-client/src/publisher/l1-publisher.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn-project/sequencer-client/src/publisher/l1-publisher.test.ts b/yarn-project/sequencer-client/src/publisher/l1-publisher.test.ts index 493acea85a90..b3de75cebbba 100644 --- a/yarn-project/sequencer-client/src/publisher/l1-publisher.test.ts +++ b/yarn-project/sequencer-client/src/publisher/l1-publisher.test.ts @@ -44,7 +44,7 @@ describe('L1Publisher', () => { status: true, logs: [{ data: '' }], } as MinimalTransactionReceipt; - txSender.sendPublishTx.mockResolvedValueOnce(processTxHash); + txSender.sendPublishTx.mockResolvedValueOnce(publishTxHash); txSender.sendProcessTx.mockResolvedValueOnce(processTxHash); txSender.getTransactionReceipt.mockResolvedValueOnce(publishTxReceipt).mockResolvedValueOnce(processTxReceipt); txSender.getCurrentArchive.mockResolvedValue(l2Block.header.lastArchive.root.toBuffer()); @@ -69,7 +69,7 @@ describe('L1Publisher', () => { }); it('does not retry if sending a publish tx fails', async () => { - txSender.sendPublishTx.mockReset().mockRejectedValueOnce(new Error()).mockResolvedValueOnce(processTxHash); + txSender.sendPublishTx.mockReset().mockRejectedValueOnce(new Error()).mockResolvedValueOnce(publishTxHash); const result = await publisher.processL2Block(l2Block); From 0354870e4e142090a2ef565cb6ac00f1714fa087 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 19 Jan 2024 08:16:45 +0000 Subject: [PATCH 13/22] linking issue --- l1-contracts/src/core/libraries/HeaderLib.sol | 2 +- yarn-project/sequencer-client/src/publisher/l1-publisher.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/l1-contracts/src/core/libraries/HeaderLib.sol b/l1-contracts/src/core/libraries/HeaderLib.sol index c6481f53ee01..894cd91ac6ab 100644 --- a/l1-contracts/src/core/libraries/HeaderLib.sol +++ b/l1-contracts/src/core/libraries/HeaderLib.sol @@ -146,7 +146,7 @@ library HeaderLib { revert Errors.Rollup__TimestampTooOld(); } - // @todo @LHerskind Proper genesis state. If the state is empty, we allow anything for now. + // TODO(#4148) Proper genesis state. If the state is empty, we allow anything for now. if (_archive != bytes32(0) && _archive != _header.lastArchive.root) { revert Errors.Rollup__InvalidArchive(_archive, _header.lastArchive.root); } diff --git a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts index a69c95c0c55c..c985c6d49aab 100644 --- a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts +++ b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts @@ -147,7 +147,7 @@ export class L1Publisher implements L2BlockReceiver { * @returns True once the tx has been confirmed and is successful, false on revert or interrupt, blocks otherwise. */ public async processL2Block(block: L2Block): Promise { - // TODO: Remove this block number check, it's here because we don't currently have proper genesis state on the contract + // TODO(#4148) Remove this block number check, it's here because we don't currently have proper genesis state on the contract const lastArchive = block.header.lastArchive.root.toBuffer(); if (block.number != 1 && !(await this.checkLastArchiveHash(lastArchive))) { this.log(`Detected different last archive prior to publishing a block, aborting publish...`); From a4ee5f9be05e5310e1973c08783f3d7ed43faa32 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 19 Jan 2024 08:41:28 +0000 Subject: [PATCH 14/22] making Availability oracle immutable again --- l1-contracts/src/core/Rollup.sol | 7 +++++-- .../core/interfaces/messagebridge/IRegistry.sol | 7 +------ .../src/core/libraries/DataStructures.sol | 2 -- l1-contracts/src/core/messagebridge/Registry.sol | 16 +++------------- l1-contracts/test/Inbox.t.sol | 4 ++-- l1-contracts/test/Outbox.t.sol | 5 ++--- l1-contracts/test/Registry.t.sol | 7 +++---- l1-contracts/test/Rollup.t.sol | 4 ++-- l1-contracts/test/portals/TokenPortal.t.sol | 8 +++----- l1-contracts/test/portals/UniswapPortal.t.sol | 8 +++----- yarn-project/ethereum/src/deploy_l1_contracts.ts | 9 ++------- 11 files changed, 26 insertions(+), 51 deletions(-) diff --git a/l1-contracts/src/core/Rollup.sol b/l1-contracts/src/core/Rollup.sol index e07079774822..036868528727 100644 --- a/l1-contracts/src/core/Rollup.sol +++ b/l1-contracts/src/core/Rollup.sol @@ -4,6 +4,7 @@ pragma solidity >=0.8.18; // Interfaces import {IRollup} from "./interfaces/IRollup.sol"; +import {IAvailabilityOracle} from "./interfaces/IAvailabilityOracle.sol"; import {IInbox} from "./interfaces/messagebridge/IInbox.sol"; import {IOutbox} from "./interfaces/messagebridge/IOutbox.sol"; import {IRegistry} from "./interfaces/messagebridge/IRegistry.sol"; @@ -26,6 +27,7 @@ import {MockVerifier} from "../mock/MockVerifier.sol"; contract Rollup is IRollup { MockVerifier public immutable VERIFIER; IRegistry public immutable REGISTRY; + IAvailabilityOracle public immutable AVAILABILITY_ORACLE; uint256 public immutable VERSION; bytes32 public archive; // Root of the archive tree @@ -34,9 +36,10 @@ contract Rollup is IRollup { // See https://github.com/AztecProtocol/aztec-packages/issues/1614 uint256 public lastWarpedBlockTs; - constructor(IRegistry _registry) { + constructor(IRegistry _registry, IAvailabilityOracle _availabilityOracle) { VERIFIER = new MockVerifier(); REGISTRY = _registry; + AVAILABILITY_ORACLE = _availabilityOracle; VERSION = 1; } @@ -60,7 +63,7 @@ contract Rollup is IRollup { HeaderLib.validate(header, VERSION, lastBlockTs, archive); // Check if the data is available using availability oracle (change availability oracle if you want a different DA layer) - if (!REGISTRY.getAvailabilityOracle().isAvailable(_txsHash)) { + if (!AVAILABILITY_ORACLE.isAvailable(_txsHash)) { revert Errors.Rollup__UnavailableTxs(_txsHash); } diff --git a/l1-contracts/src/core/interfaces/messagebridge/IRegistry.sol b/l1-contracts/src/core/interfaces/messagebridge/IRegistry.sol index 426dcdf3a474..0d184a521f21 100644 --- a/l1-contracts/src/core/interfaces/messagebridge/IRegistry.sol +++ b/l1-contracts/src/core/interfaces/messagebridge/IRegistry.sol @@ -5,13 +5,10 @@ import {DataStructures} from "../../libraries/DataStructures.sol"; import {IRollup} from "../IRollup.sol"; import {IInbox} from "./IInbox.sol"; import {IOutbox} from "./IOutbox.sol"; -import {IAvailabilityOracle} from "../../interfaces/IAvailabilityOracle.sol"; interface IRegistry { // docs:start:registry_upgrade - function upgrade(address _rollup, address _inbox, address _outbox, address _availabilityOracle) - external - returns (uint256); + function upgrade(address _rollup, address _inbox, address _outbox) external returns (uint256); // docs:end:registry_upgrade // docs:start:registry_get_rollup @@ -30,8 +27,6 @@ interface IRegistry { function getOutbox() external view returns (IOutbox); // docs:end:registry_get_outbox - function getAvailabilityOracle() external view returns (IAvailabilityOracle); - // docs:start:registry_get_snapshot function getSnapshot(uint256 _version) external diff --git a/l1-contracts/src/core/libraries/DataStructures.sol b/l1-contracts/src/core/libraries/DataStructures.sol index 465e0bf11f8a..f588c7c1d4d6 100644 --- a/l1-contracts/src/core/libraries/DataStructures.sol +++ b/l1-contracts/src/core/libraries/DataStructures.sol @@ -88,14 +88,12 @@ library DataStructures { * @param rollup - The address of the rollup contract * @param inbox - The address of the inbox contract * @param outbox - The address of the outbox contract - * @param availabilityOracle - The address of the availability oracle contract * @param blockNumber - The block number of the snapshot */ struct RegistrySnapshot { address rollup; address inbox; address outbox; - address availabilityOracle; uint256 blockNumber; } // docs:end:registry_snapshot diff --git a/l1-contracts/src/core/messagebridge/Registry.sol b/l1-contracts/src/core/messagebridge/Registry.sol index 73de83fbb604..947597c8b02f 100644 --- a/l1-contracts/src/core/messagebridge/Registry.sol +++ b/l1-contracts/src/core/messagebridge/Registry.sol @@ -7,7 +7,6 @@ import {IRegistry} from "../interfaces/messagebridge/IRegistry.sol"; import {IRollup} from "../interfaces/IRollup.sol"; import {IInbox} from "../interfaces/messagebridge/IInbox.sol"; import {IOutbox} from "../interfaces/messagebridge/IOutbox.sol"; -import {IAvailabilityOracle} from "../interfaces/IAvailabilityOracle.sol"; // Libraries import {DataStructures} from "../libraries/DataStructures.sol"; @@ -30,7 +29,7 @@ contract Registry is IRegistry { constructor() { // Inserts a "dead" rollup and message boxes at version 0 // This is simply done to make first version 1, which fits better with the rest of the system - upgrade(address(0xdead), address(0xdead), address(0xdead), address(0xdead)); + upgrade(address(0xdead), address(0xdead), address(0xdead)); } /** @@ -68,14 +67,6 @@ contract Registry is IRegistry { return IOutbox(currentSnapshot.outbox); } - /** - * @notice Returns the availability oracle contract - * @return The availability oracle contract (of type IAvailabilityOracle) - */ - function getAvailabilityOracle() external view override(IRegistry) returns (IAvailabilityOracle) { - return IAvailabilityOracle(currentSnapshot.availabilityOracle); - } - /** * @notice Fetches a snapshot of the registry indicated by `version` * @dev the version is 0 indexed, so the first snapshot is version 0. @@ -111,10 +102,9 @@ contract Registry is IRegistry { * @param _rollup - The address of the rollup contract * @param _inbox - The address of the inbox contract * @param _outbox - The address of the outbox contract - * @param _availabilityOracle - The address of the availability oracle contract * @return The version of the new snapshot */ - function upgrade(address _rollup, address _inbox, address _outbox, address _availabilityOracle) + function upgrade(address _rollup, address _inbox, address _outbox) public override(IRegistry) returns (uint256) @@ -123,7 +113,7 @@ contract Registry is IRegistry { if (exists) revert Errors.Registry__RollupAlreadyRegistered(_rollup); DataStructures.RegistrySnapshot memory newSnapshot = - DataStructures.RegistrySnapshot(_rollup, _inbox, _outbox, _availabilityOracle, block.number); + DataStructures.RegistrySnapshot(_rollup, _inbox, _outbox, block.number); currentSnapshot = newSnapshot; uint256 version = numberOfVersions++; snapshots[version] = newSnapshot; diff --git a/l1-contracts/test/Inbox.t.sol b/l1-contracts/test/Inbox.t.sol index 57b1a0df8d1c..a120aa0bb394 100644 --- a/l1-contracts/test/Inbox.t.sol +++ b/l1-contracts/test/Inbox.t.sol @@ -35,7 +35,7 @@ contract InboxTest is Test { address rollup = address(this); registry = new Registry(); inbox = new Inbox(address(registry)); - version = registry.upgrade(rollup, address(inbox), address(0x0), address(0x0)); + version = registry.upgrade(rollup, address(inbox), address(0x0)); } function _fakeMessage() internal view returns (DataStructures.L1ToL2Msg memory) { @@ -254,7 +254,7 @@ contract InboxTest is Test { function testRevertIfConsumingFromWrongRollup() public { address wrongRollup = address(0xbeeffeed); - uint256 wrongVersion = registry.upgrade(wrongRollup, address(inbox), address(0x0), address(0x0)); + uint256 wrongVersion = registry.upgrade(wrongRollup, address(inbox), address(0x0)); DataStructures.L1ToL2Msg memory message = _fakeMessage(); address feeCollector = address(0x1); diff --git a/l1-contracts/test/Outbox.t.sol b/l1-contracts/test/Outbox.t.sol index cecc5d02c045..4ad45b5abc3f 100644 --- a/l1-contracts/test/Outbox.t.sol +++ b/l1-contracts/test/Outbox.t.sol @@ -22,7 +22,7 @@ contract OutboxTest is Test { address rollup = address(this); registry = new Registry(); outbox = new Outbox(address(registry)); - version = registry.upgrade(rollup, address(0x0), address(outbox), address(0x0)); + version = registry.upgrade(rollup, address(0x0), address(outbox)); } function _fakeMessage() internal view returns (DataStructures.L2ToL1Msg memory) { @@ -89,8 +89,7 @@ contract OutboxTest is Test { function testRevertIfInsertingFromWrongRollup() public { address wrongRollup = address(0xbeeffeed); - uint256 wrongVersion = - registry.upgrade(wrongRollup, address(0x0), address(outbox), address(0x0)); + uint256 wrongVersion = registry.upgrade(wrongRollup, address(0x0), address(outbox)); DataStructures.L2ToL1Msg memory message = _fakeMessage(); // correctly set message.recipient to this address diff --git a/l1-contracts/test/Registry.t.sol b/l1-contracts/test/Registry.t.sol index 6ee8f2e76c99..6d844c478aff 100644 --- a/l1-contracts/test/Registry.t.sol +++ b/l1-contracts/test/Registry.t.sol @@ -38,8 +38,7 @@ contract RegistryTest is Test { address newRollup = address(0xbeef1); address newInbox = address(0xbeef2); address newOutbox = address(0xbeef3); - address newAvailabilityOracle = address(0xbeef4); - uint256 newVersion = registry.upgrade(newRollup, newInbox, newOutbox, newAvailabilityOracle); + uint256 newVersion = registry.upgrade(newRollup, newInbox, newOutbox); assertEq(registry.numberOfVersions(), 2, "should have 2 versions"); DataStructures.RegistrySnapshot memory snapshot = registry.getCurrentSnapshot(); @@ -56,9 +55,9 @@ contract RegistryTest is Test { } function testRevertUpgradeToSame() public { - registry.upgrade(DEAD, DEAD, DEAD, DEAD); + registry.upgrade(DEAD, DEAD, DEAD); vm.expectRevert(abi.encodeWithSelector(Errors.Registry__RollupAlreadyRegistered.selector, DEAD)); - registry.upgrade(DEAD, DEAD, DEAD, DEAD); + registry.upgrade(DEAD, DEAD, DEAD); } function testRevertGetVersionForNonExistent() public { diff --git a/l1-contracts/test/Rollup.t.sol b/l1-contracts/test/Rollup.t.sol index 7c45d0323749..387dcbac6a85 100644 --- a/l1-contracts/test/Rollup.t.sol +++ b/l1-contracts/test/Rollup.t.sol @@ -36,10 +36,10 @@ contract RollupTest is DecoderBase { registry = new Registry(); inbox = new Inbox(address(registry)); outbox = new Outbox(address(registry)); - rollup = new Rollup(registry); availabilityOracle = new AvailabilityOracle(); + rollup = new Rollup(registry, availabilityOracle); - registry.upgrade(address(rollup), address(inbox), address(outbox), address(availabilityOracle)); + registry.upgrade(address(rollup), address(inbox), address(outbox)); } function testMixedBlock() public { diff --git a/l1-contracts/test/portals/TokenPortal.t.sol b/l1-contracts/test/portals/TokenPortal.t.sol index 0ac38d7e426c..25457ab2c9a3 100644 --- a/l1-contracts/test/portals/TokenPortal.t.sol +++ b/l1-contracts/test/portals/TokenPortal.t.sol @@ -4,10 +4,10 @@ import "forge-std/Test.sol"; // Rollup Processor import {Rollup} from "../../src/core/Rollup.sol"; +import {AvailabilityOracle} from "../../src/core/availability_oracle/AvailabilityOracle.sol"; import {Inbox} from "../../src/core/messagebridge/Inbox.sol"; import {Registry} from "../../src/core/messagebridge/Registry.sol"; import {Outbox} from "../../src/core/messagebridge/Outbox.sol"; -import {AvailabilityOracle} from "../../src/core/availability_oracle/AvailabilityOracle.sol"; import {DataStructures} from "../../src/core/libraries/DataStructures.sol"; import {Hash} from "../../src/core/libraries/Hash.sol"; import {Errors} from "../../src/core/libraries/Errors.sol"; @@ -39,7 +39,6 @@ contract TokenPortalTest is Test { Inbox internal inbox; Outbox internal outbox; Rollup internal rollup; - AvailabilityOracle internal availabilityOracle; bytes32 internal l2TokenAddress = bytes32(uint256(0x42)); TokenPortal internal tokenPortal; @@ -66,10 +65,9 @@ contract TokenPortalTest is Test { registry = new Registry(); inbox = new Inbox(address(registry)); outbox = new Outbox(address(registry)); - rollup = new Rollup(registry); - availabilityOracle = new AvailabilityOracle(); + rollup = new Rollup(registry, new AvailabilityOracle()); - registry.upgrade(address(rollup), address(inbox), address(outbox), address(availabilityOracle)); + registry.upgrade(address(rollup), address(inbox), address(outbox)); portalERC20 = new PortalERC20(); tokenPortal = new TokenPortal(); diff --git a/l1-contracts/test/portals/UniswapPortal.t.sol b/l1-contracts/test/portals/UniswapPortal.t.sol index df12cf2e4c33..454985b248b9 100644 --- a/l1-contracts/test/portals/UniswapPortal.t.sol +++ b/l1-contracts/test/portals/UniswapPortal.t.sol @@ -4,10 +4,10 @@ import "forge-std/Test.sol"; // Rollup Processor import {Rollup} from "../../src/core/Rollup.sol"; +import {AvailabilityOracle} from "../../src/core/availability_oracle/AvailabilityOracle.sol"; import {Inbox} from "../../src/core/messagebridge/Inbox.sol"; import {Registry} from "../../src/core/messagebridge/Registry.sol"; import {Outbox} from "../../src/core/messagebridge/Outbox.sol"; -import {AvailabilityOracle} from "../../src/core/availability_oracle/AvailabilityOracle.sol"; import {DataStructures} from "../../src/core/libraries/DataStructures.sol"; import {Hash} from "../../src/core/libraries/Hash.sol"; import {Errors} from "../../src/core/libraries/Errors.sol"; @@ -28,7 +28,6 @@ contract UniswapPortalTest is Test { Inbox internal inbox; Outbox internal outbox; Rollup internal rollup; - AvailabilityOracle internal availabilityOracle; bytes32 internal l2TokenAddress = bytes32(uint256(0x1)); bytes32 internal l2UniswapAddress = bytes32(uint256(0x2)); @@ -53,9 +52,8 @@ contract UniswapPortalTest is Test { Registry registry = new Registry(); inbox = new Inbox(address(registry)); outbox = new Outbox(address(registry)); - rollup = new Rollup(registry); - availabilityOracle = new AvailabilityOracle(); - registry.upgrade(address(rollup), address(inbox), address(outbox), address(availabilityOracle)); + rollup = new Rollup(registry, new AvailabilityOracle()); + registry.upgrade(address(rollup), address(inbox), address(outbox)); daiTokenPortal = new TokenPortal(); daiTokenPortal.initialize(address(registry), address(DAI), l2TokenAddress); diff --git a/yarn-project/ethereum/src/deploy_l1_contracts.ts b/yarn-project/ethereum/src/deploy_l1_contracts.ts index a15623d4fd75..689423cf8346 100644 --- a/yarn-project/ethereum/src/deploy_l1_contracts.ts +++ b/yarn-project/ethereum/src/deploy_l1_contracts.ts @@ -149,7 +149,7 @@ export const deployL1Contracts = async ( publicClient, contractsToDeploy.rollup.contractAbi, contractsToDeploy.rollup.contractBytecode, - [getAddress(registryAddress.toString())], + [getAddress(registryAddress.toString()), getAddress(availabilityOracleAddress.toString())], ); logger(`Deployed Rollup at ${rollupAddress}`); @@ -161,12 +161,7 @@ export const deployL1Contracts = async ( walletClient, }); await registryContract.write.upgrade( - [ - getAddress(rollupAddress.toString()), - getAddress(inboxAddress.toString()), - getAddress(outboxAddress.toString()), - getAddress(availabilityOracleAddress.toString()), - ], + [getAddress(rollupAddress.toString()), getAddress(inboxAddress.toString()), getAddress(outboxAddress.toString())], { account }, ); From 6a9cbd0feac77373cf49514dd58af4d6748c8121 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 18 Jan 2024 15:30:21 +0000 Subject: [PATCH 15/22] refactor: contract deployment cleanup --- yarn-project/aztec-sandbox/src/sandbox.ts | 51 +--------- yarn-project/aztec.js/src/api/ethereum.ts | 7 +- yarn-project/aztec.js/src/index.ts | 7 +- yarn-project/cli/src/utils.ts | 42 +------- yarn-project/end-to-end/src/fixtures/utils.ts | 62 +----------- .../src/integration_l1_publisher.test.ts | 16 +-- yarn-project/ethereum/package.json | 1 + .../ethereum/src/deploy_l1_contracts.ts | 98 ++++++------------- yarn-project/yarn.lock | 1 + 9 files changed, 49 insertions(+), 236 deletions(-) diff --git a/yarn-project/aztec-sandbox/src/sandbox.ts b/yarn-project/aztec-sandbox/src/sandbox.ts index acb868e4bca4..b0c55e4c5ba8 100644 --- a/yarn-project/aztec-sandbox/src/sandbox.ts +++ b/yarn-project/aztec-sandbox/src/sandbox.ts @@ -1,29 +1,9 @@ #!/usr/bin/env -S node --no-warnings import { AztecNodeConfig, AztecNodeService, getConfigEnvVars } from '@aztec/aztec-node'; import { AztecNode } from '@aztec/circuit-types'; -import { - DeployL1Contracts, - L1ContractArtifactsForDeployment, - NULL_KEY, - createEthereumChain, - deployL1Contracts, -} from '@aztec/ethereum'; +import { DeployL1Contracts, NULL_KEY, createEthereumChain, deployL1Contracts } from '@aztec/ethereum'; import { createDebugLogger } from '@aztec/foundation/log'; import { retryUntil } from '@aztec/foundation/retry'; -import { - AvailabilityOracleAbi, - AvailabilityOracleBytecode, - ContractDeploymentEmitterAbi, - ContractDeploymentEmitterBytecode, - InboxAbi, - InboxBytecode, - OutboxAbi, - OutboxBytecode, - RegistryAbi, - RegistryBytecode, - RollupAbi, - RollupBytecode, -} from '@aztec/l1-artifacts'; import { PXEServiceConfig, createPXEService, getPXEServiceConfig } from '@aztec/pxe'; import { HDAccount, createPublicClient, http as httpViemTransport } from 'viem'; @@ -75,36 +55,9 @@ async function waitThenDeploy(config: AztecNodeConfig, deployFunction: () => Pro * @param hdAccount - Account for publishing L1 contracts */ export async function deployContractsToL1(aztecNodeConfig: AztecNodeConfig, hdAccount: HDAccount) { - const l1Artifacts: L1ContractArtifactsForDeployment = { - contractDeploymentEmitter: { - contractAbi: ContractDeploymentEmitterAbi, - contractBytecode: ContractDeploymentEmitterBytecode, - }, - registry: { - contractAbi: RegistryAbi, - contractBytecode: RegistryBytecode, - }, - inbox: { - contractAbi: InboxAbi, - contractBytecode: InboxBytecode, - }, - outbox: { - contractAbi: OutboxAbi, - contractBytecode: OutboxBytecode, - }, - availabilityOracle: { - contractAbi: AvailabilityOracleAbi, - contractBytecode: AvailabilityOracleBytecode, - }, - rollup: { - contractAbi: RollupAbi, - contractBytecode: RollupBytecode, - }, - }; - aztecNodeConfig.l1Contracts = ( await waitThenDeploy(aztecNodeConfig, () => - deployL1Contracts(aztecNodeConfig.rpcUrl, hdAccount, localAnvil, logger, l1Artifacts), + deployL1Contracts(aztecNodeConfig.rpcUrl, hdAccount, localAnvil, logger), ) ).l1ContractAddresses; diff --git a/yarn-project/aztec.js/src/api/ethereum.ts b/yarn-project/aztec.js/src/api/ethereum.ts index 5be2a7ac37dc..fef9478c29f5 100644 --- a/yarn-project/aztec.js/src/api/ethereum.ts +++ b/yarn-project/aztec.js/src/api/ethereum.ts @@ -1,6 +1 @@ -export { - deployL1Contract, - deployL1Contracts, - DeployL1Contracts, - L1ContractArtifactsForDeployment, -} from '@aztec/ethereum'; +export { deployL1Contract, deployL1Contracts, DeployL1Contracts } from '@aztec/ethereum'; diff --git a/yarn-project/aztec.js/src/index.ts b/yarn-project/aztec.js/src/index.ts index ff2378a23bf7..f3a8feab10f1 100644 --- a/yarn-project/aztec.js/src/index.ts +++ b/yarn-project/aztec.js/src/index.ts @@ -125,12 +125,7 @@ export { toBigIntBE } from '@aztec/foundation/bigint-buffer'; export { makeFetch } from '@aztec/foundation/json-rpc/client'; export { FieldsOf } from '@aztec/foundation/types'; -export { - DeployL1Contracts, - L1ContractArtifactsForDeployment, - deployL1Contract, - deployL1Contracts, -} from '@aztec/ethereum'; +export { DeployL1Contracts, deployL1Contract, deployL1Contracts } from '@aztec/ethereum'; // Start of section that exports public api via granular api. // Here you *can* do `export *` as the granular api defacto exports things explicitly. diff --git a/yarn-project/cli/src/utils.ts b/yarn-project/cli/src/utils.ts index a3926ae67502..87933f75392f 100644 --- a/yarn-project/cli/src/utils.ts +++ b/yarn-project/cli/src/utils.ts @@ -1,10 +1,8 @@ import { type ContractArtifact, type FunctionArtifact } from '@aztec/aztec.js/abi'; import { AztecAddress } from '@aztec/aztec.js/aztec_address'; -import { type L1ContractArtifactsForDeployment } from '@aztec/aztec.js/ethereum'; import { type PXE } from '@aztec/aztec.js/interfaces/pxe'; import { DebugLogger, LogFn } from '@aztec/foundation/log'; import { NoirPackageConfig } from '@aztec/foundation/noir'; -import { AvailabilityOracleAbi, AvailabilityOracleBytecode } from '@aztec/l1-artifacts'; import TOML from '@iarna/toml'; import { CommanderError, InvalidArgumentError } from 'commander'; @@ -47,50 +45,12 @@ export async function deployAztecContracts( mnemonic: string, debugLogger: DebugLogger, ) { - const { - ContractDeploymentEmitterAbi, - ContractDeploymentEmitterBytecode, - InboxAbi, - InboxBytecode, - OutboxAbi, - OutboxBytecode, - RegistryAbi, - RegistryBytecode, - RollupAbi, - RollupBytecode, - } = await import('@aztec/l1-artifacts'); const { createEthereumChain, deployL1Contracts } = await import('@aztec/ethereum'); const { mnemonicToAccount, privateKeyToAccount } = await import('viem/accounts'); const account = !privateKey ? mnemonicToAccount(mnemonic!) : privateKeyToAccount(`0x${privateKey}`); const chain = createEthereumChain(rpcUrl, apiKey); - const l1Artifacts: L1ContractArtifactsForDeployment = { - contractDeploymentEmitter: { - contractAbi: ContractDeploymentEmitterAbi, - contractBytecode: ContractDeploymentEmitterBytecode, - }, - registry: { - contractAbi: RegistryAbi, - contractBytecode: RegistryBytecode, - }, - inbox: { - contractAbi: InboxAbi, - contractBytecode: InboxBytecode, - }, - outbox: { - contractAbi: OutboxAbi, - contractBytecode: OutboxBytecode, - }, - availabilityOracle: { - contractAbi: AvailabilityOracleAbi, - contractBytecode: AvailabilityOracleBytecode, - }, - rollup: { - contractAbi: RollupAbi, - contractBytecode: RollupBytecode, - }, - }; - return await deployL1Contracts(chain.rpcUrl, account, chain.chainInfo, debugLogger, l1Artifacts); + return await deployL1Contracts(chain.rpcUrl, account, chain.chainInfo, debugLogger); } /** diff --git a/yarn-project/end-to-end/src/fixtures/utils.ts b/yarn-project/end-to-end/src/fixtures/utils.ts index 8942bded2971..a187d00a975f 100644 --- a/yarn-project/end-to-end/src/fixtures/utils.ts +++ b/yarn-project/end-to-end/src/fixtures/utils.ts @@ -8,7 +8,6 @@ import { DebugLogger, DeployL1Contracts, EthCheatCodes, - L1ContractArtifactsForDeployment, L2BlockL2Logs, LogType, PXE, @@ -19,34 +18,11 @@ import { deployL1Contracts, waitForPXE, } from '@aztec/aztec.js'; -import { - AvailabilityOracleAbi, - AvailabilityOracleBytecode, - ContractDeploymentEmitterAbi, - ContractDeploymentEmitterBytecode, - InboxAbi, - InboxBytecode, - OutboxAbi, - OutboxBytecode, - RegistryAbi, - RegistryBytecode, - RollupAbi, - RollupBytecode, -} from '@aztec/l1-artifacts'; import { PXEService, PXEServiceConfig, createPXEService, getPXEServiceConfig } from '@aztec/pxe'; import { SequencerClient } from '@aztec/sequencer-client'; import * as path from 'path'; -import { - Account, - Chain, - HDAccount, - HttpTransport, - PrivateKeyAccount, - createPublicClient, - createWalletClient, - http, -} from 'viem'; +import { Account, Chain, HDAccount, HttpTransport, createPublicClient, createWalletClient, http } from 'viem'; import { mnemonicToAccount } from 'viem/accounts'; import { MNEMONIC, localAnvil } from './fixtures.js'; @@ -67,40 +43,6 @@ const getAztecNodeUrl = () => { return url.toString(); }; -export const setupL1Contracts = async ( - l1RpcUrl: string, - account: HDAccount | PrivateKeyAccount, - logger: DebugLogger, -) => { - const l1Artifacts: L1ContractArtifactsForDeployment = { - contractDeploymentEmitter: { - contractAbi: ContractDeploymentEmitterAbi, - contractBytecode: ContractDeploymentEmitterBytecode, - }, - registry: { - contractAbi: RegistryAbi, - contractBytecode: RegistryBytecode, - }, - inbox: { - contractAbi: InboxAbi, - contractBytecode: InboxBytecode, - }, - outbox: { - contractAbi: OutboxAbi, - contractBytecode: OutboxBytecode, - }, - availabilityOracle: { - contractAbi: AvailabilityOracleAbi, - contractBytecode: AvailabilityOracleBytecode, - }, - rollup: { - contractAbi: RollupAbi, - contractBytecode: RollupBytecode, - }, - }; - return await deployL1Contracts(l1RpcUrl, account, localAnvil, logger, l1Artifacts); -}; - /** * Sets up Private eXecution Environment (PXE). * @param numberOfAccounts - The number of new accounts to be created once the PXE is initiated. @@ -282,7 +224,7 @@ export async function setup( } const deployL1ContractsValues = - opts.deployL1ContractsValues ?? (await setupL1Contracts(config.rpcUrl, hdAccount, logger)); + opts.deployL1ContractsValues ?? (await deployL1Contracts(config.rpcUrl, hdAccount, localAnvil, logger)); config.publisherPrivateKey = `0x${publisherPrivKey!.toString('hex')}`; config.l1Contracts = deployL1ContractsValues.l1ContractAddresses; diff --git a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts index be9d3ddad02c..302dba682071 100644 --- a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts +++ b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts @@ -26,7 +26,7 @@ import { makeNewSideEffectLinkedToNoteHash, makeProof, } from '@aztec/circuits.js/factories'; -import { createEthereumChain } from '@aztec/ethereum'; +import { createEthereumChain, deployL1Contracts } from '@aztec/ethereum'; import { makeTuple, range } from '@aztec/foundation/array'; import { InboxAbi, OutboxAbi, RollupAbi } from '@aztec/l1-artifacts'; import { @@ -60,7 +60,7 @@ import { } from 'viem'; import { PrivateKeyAccount, privateKeyToAccount } from 'viem/accounts'; -import { setupL1Contracts } from './fixtures/utils.js'; +import { localAnvil } from './fixtures/fixtures.js'; // Accounts 4 and 5 of Anvil default startup with mnemonic: 'test test test test test test test test test test test junk' const sequencerPK = '0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a'; @@ -104,12 +104,12 @@ describe('L1Publisher integration', () => { beforeEach(async () => { deployerAccount = privateKeyToAccount(deployerPK); - const { - l1ContractAddresses, - walletClient, - publicClient: publicClient_, - } = await setupL1Contracts(config.rpcUrl, deployerAccount, logger); - publicClient = publicClient_; + const { walletClient, publicClient, l1ContractAddresses } = await deployL1Contracts( + config.rpcUrl, + deployerAccount, + localAnvil, + logger, + ); rollupAddress = getAddress(l1ContractAddresses.rollupAddress.toString()); inboxAddress = getAddress(l1ContractAddresses.inboxAddress.toString()); diff --git a/yarn-project/ethereum/package.json b/yarn-project/ethereum/package.json index 6e381965005f..a0d8c31d58d3 100644 --- a/yarn-project/ethereum/package.json +++ b/yarn-project/ethereum/package.json @@ -25,6 +25,7 @@ ], "dependencies": { "@aztec/foundation": "workspace:^", + "@aztec/l1-artifacts": "workspace:^", "dotenv": "^16.0.3", "tslib": "^2.4.0", "viem": "^1.2.5" diff --git a/yarn-project/ethereum/src/deploy_l1_contracts.ts b/yarn-project/ethereum/src/deploy_l1_contracts.ts index 689423cf8346..c098f20d1a66 100644 --- a/yarn-project/ethereum/src/deploy_l1_contracts.ts +++ b/yarn-project/ethereum/src/deploy_l1_contracts.ts @@ -1,5 +1,19 @@ import { EthAddress } from '@aztec/foundation/eth-address'; import { DebugLogger } from '@aztec/foundation/log'; +import { + AvailabilityOracleAbi, + AvailabilityOracleBytecode, + ContractDeploymentEmitterAbi, + ContractDeploymentEmitterBytecode, + InboxAbi, + InboxBytecode, + OutboxAbi, + OutboxBytecode, + RegistryAbi, + RegistryBytecode, + RollupAbi, + RollupBytecode, +} from '@aztec/l1-artifacts'; import type { Abi, Narrow } from 'abitype'; import { @@ -52,43 +66,12 @@ export interface ContractArtifacts { contractBytecode: Hex; } -/** - * All L1 Contract Artifacts for deployment - */ -export interface L1ContractArtifactsForDeployment { - /** - * Contract deployment emitter artifacts - */ - contractDeploymentEmitter: ContractArtifacts; - /** - * Inbox contract artifacts - */ - inbox: ContractArtifacts; - /** - * Outbox contract artifacts - */ - outbox: ContractArtifacts; - /** - * Availability Oracle contract artifacts - */ - availabilityOracle: ContractArtifacts; - /** - * Registry contract artifacts - */ - registry: ContractArtifacts; - /** - * Rollup contract artifacts - */ - rollup: ContractArtifacts; -} - /** * Deploys the aztec L1 contracts; Rollup, Contract Deployment Emitter & (optionally) Decoder Helper. * @param rpcUrl - URL of the ETH RPC to use for deployment. * @param account - Private Key or HD Account that will deploy the contracts. * @param chain - The chain instance to deploy to. * @param logger - A logger object. - * @param contractsToDeploy - The set of L1 artifacts to be deployed * @returns A list of ETH addresses of the deployed contracts. */ export const deployL1Contracts = async ( @@ -96,7 +79,6 @@ export const deployL1Contracts = async ( account: HDAccount | PrivateKeyAccount, chain: Chain, logger: DebugLogger, - contractsToDeploy: L1ContractArtifactsForDeployment, ): Promise => { logger('Deploying contracts...'); @@ -110,53 +92,37 @@ export const deployL1Contracts = async ( transport: http(rpcUrl), }); - const registryAddress = await deployL1Contract( - walletClient, - publicClient, - contractsToDeploy.registry.contractAbi, - contractsToDeploy.registry.contractBytecode, - ); + const registryAddress = await deployL1Contract(walletClient, publicClient, RegistryAbi, RegistryBytecode); logger(`Deployed Registry at ${registryAddress}`); - const inboxAddress = await deployL1Contract( - walletClient, - publicClient, - contractsToDeploy.inbox.contractAbi, - contractsToDeploy.inbox.contractBytecode, - [getAddress(registryAddress.toString())], - ); + const inboxAddress = await deployL1Contract(walletClient, publicClient, InboxAbi, InboxBytecode, [ + getAddress(registryAddress.toString()), + ]); logger(`Deployed Inbox at ${inboxAddress}`); - const outboxAddress = await deployL1Contract( - walletClient, - publicClient, - contractsToDeploy.outbox.contractAbi, - contractsToDeploy.outbox.contractBytecode, - [getAddress(registryAddress.toString())], - ); + const outboxAddress = await deployL1Contract(walletClient, publicClient, OutboxAbi, OutboxBytecode, [ + getAddress(registryAddress.toString()), + ]); logger(`Deployed Outbox at ${outboxAddress}`); const availabilityOracleAddress = await deployL1Contract( walletClient, publicClient, - contractsToDeploy.availabilityOracle.contractAbi, - contractsToDeploy.availabilityOracle.contractBytecode, + AvailabilityOracleAbi, + AvailabilityOracleBytecode, ); logger(`Deployed AvailabilityOracle at ${availabilityOracleAddress}`); - const rollupAddress = await deployL1Contract( - walletClient, - publicClient, - contractsToDeploy.rollup.contractAbi, - contractsToDeploy.rollup.contractBytecode, - [getAddress(registryAddress.toString()), getAddress(availabilityOracleAddress.toString())], - ); + + const rollupAddress = await deployL1Contract(walletClient, publicClient, RollupAbi, RollupBytecode, [ + getAddress(registryAddress.toString()), getAddress(availabilityOracleAddress.toString()), + ]); logger(`Deployed Rollup at ${rollupAddress}`); // We need to call a function on the registry to set the various contract addresses. const registryContract = getContract({ address: getAddress(registryAddress.toString()), - abi: contractsToDeploy.registry.contractAbi, + abi: RegistryAbi, publicClient, walletClient, }); @@ -168,12 +134,12 @@ export const deployL1Contracts = async ( const contractDeploymentEmitterAddress = await deployL1Contract( walletClient, publicClient, - contractsToDeploy.contractDeploymentEmitter.contractAbi, - contractsToDeploy.contractDeploymentEmitter.contractBytecode, + ContractDeploymentEmitterAbi, + ContractDeploymentEmitterBytecode, ); logger(`Deployed contract deployment emitter at ${contractDeploymentEmitterAddress}`); - const l1Contracts: L1ContractAddresses = { + const l1ContractAddresses: L1ContractAddresses = { availabilityOracleAddress, rollupAddress, registryAddress, @@ -185,7 +151,7 @@ export const deployL1Contracts = async ( return { walletClient, publicClient, - l1ContractAddresses: l1Contracts, + l1ContractAddresses, }; }; diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index d29459822903..1d7706ccef95 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -453,6 +453,7 @@ __metadata: resolution: "@aztec/ethereum@workspace:ethereum" dependencies: "@aztec/foundation": "workspace:^" + "@aztec/l1-artifacts": "workspace:^" "@jest/globals": ^29.5.0 "@types/jest": ^29.5.0 "@types/node": ^18.14.6 From 05428bc5a018f3f685cabd3ec717175faf6477e0 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 18 Jan 2024 15:53:14 +0000 Subject: [PATCH 16/22] nuking redundant functions --- yarn-project/aztec-sandbox/src/bin/index.ts | 4 +-- yarn-project/aztec-sandbox/src/sandbox.ts | 27 ++++++------------- .../cli/src/cmds/deploy_l1_contracts.ts | 18 ++++++++++--- yarn-project/cli/src/utils.ts | 24 +---------------- yarn-project/ethereum/tsconfig.json | 3 +++ 5 files changed, 28 insertions(+), 48 deletions(-) diff --git a/yarn-project/aztec-sandbox/src/bin/index.ts b/yarn-project/aztec-sandbox/src/bin/index.ts index 97aa2d790ea1..f113624e34fc 100644 --- a/yarn-project/aztec-sandbox/src/bin/index.ts +++ b/yarn-project/aztec-sandbox/src/bin/index.ts @@ -17,7 +17,7 @@ import { dirname, resolve } from 'path'; import { mnemonicToAccount } from 'viem/accounts'; import { setupFileDebugLog } from '../logging.js'; -import { MNEMONIC, createAztecNode, createAztecPXE, createSandbox, deployContractsToL1 } from '../sandbox.js'; +import { MNEMONIC, createAztecNode, createAztecPXE, createSandbox, waitThenDeployL1Contracts } from '../sandbox.js'; import { github, splash } from '../splash.js'; /** @@ -146,7 +146,7 @@ async function main() { // Deploy L1 Aztec Contracts if needed if (deployAztecContracts) { - await deployContractsToL1(nodeConfig, hdAccount); + await waitThenDeployL1Contracts(nodeConfig, hdAccount); if (nodeConfig.publisherPrivateKey === NULL_KEY) { const privKey = hdAccount.getHdKey().privateKey; nodeConfig.publisherPrivateKey = `0x${Buffer.from(privKey!).toString('hex')}`; diff --git a/yarn-project/aztec-sandbox/src/sandbox.ts b/yarn-project/aztec-sandbox/src/sandbox.ts index b0c55e4c5ba8..6ab05a950acf 100644 --- a/yarn-project/aztec-sandbox/src/sandbox.ts +++ b/yarn-project/aztec-sandbox/src/sandbox.ts @@ -1,7 +1,7 @@ #!/usr/bin/env -S node --no-warnings import { AztecNodeConfig, AztecNodeService, getConfigEnvVars } from '@aztec/aztec-node'; import { AztecNode } from '@aztec/circuit-types'; -import { DeployL1Contracts, NULL_KEY, createEthereumChain, deployL1Contracts } from '@aztec/ethereum'; +import { NULL_KEY, createEthereumChain, deployL1Contracts } from '@aztec/ethereum'; import { createDebugLogger } from '@aztec/foundation/log'; import { retryUntil } from '@aztec/foundation/retry'; import { PXEServiceConfig, createPXEService, getPXEServiceConfig } from '@aztec/pxe'; @@ -17,9 +17,11 @@ const logger = createDebugLogger('aztec:sandbox'); const localAnvil = foundry; /** - * Helper function that waits for the Ethereum RPC server to respond before deploying L1 contracts. + * Waits then deploys L1 contracts. + * @param config - The Aztec Node Config. + * @param hdAccount - Account for publishing L1 contracts. */ -async function waitThenDeploy(config: AztecNodeConfig, deployFunction: () => Promise) { +export async function waitThenDeployL1Contracts(config: AztecNodeConfig, hdAccount: HDAccount) { const chain = createEthereumChain(config.rpcUrl, config.apiKey); // wait for ETH RPC to respond to a request. const publicClient = createPublicClient({ @@ -46,22 +48,9 @@ async function waitThenDeploy(config: AztecNodeConfig, deployFunction: () => Pro } // Deploy L1 contracts - return await deployFunction(); -} + config.l1Contracts = (await deployL1Contracts(config.rpcUrl, hdAccount, localAnvil, logger)).l1ContractAddresses; -/** - * Function to deploy our L1 contracts to the sandbox L1 - * @param aztecNodeConfig - The Aztec Node Config - * @param hdAccount - Account for publishing L1 contracts - */ -export async function deployContractsToL1(aztecNodeConfig: AztecNodeConfig, hdAccount: HDAccount) { - aztecNodeConfig.l1Contracts = ( - await waitThenDeploy(aztecNodeConfig, () => - deployL1Contracts(aztecNodeConfig.rpcUrl, hdAccount, localAnvil, logger), - ) - ).l1ContractAddresses; - - return aztecNodeConfig.l1Contracts; + return config.l1Contracts; } /** Sandbox settings. */ @@ -84,7 +73,7 @@ export async function createSandbox(config: Partial = {}) { } if (!aztecNodeConfig.p2pEnabled) { - await deployContractsToL1(aztecNodeConfig, hdAccount); + await waitThenDeployL1Contracts(aztecNodeConfig, hdAccount); } const node = await createAztecNode(aztecNodeConfig); diff --git a/yarn-project/cli/src/cmds/deploy_l1_contracts.ts b/yarn-project/cli/src/cmds/deploy_l1_contracts.ts index 3b45537d88a6..5c1b1cd3534b 100644 --- a/yarn-project/cli/src/cmds/deploy_l1_contracts.ts +++ b/yarn-project/cli/src/cmds/deploy_l1_contracts.ts @@ -1,9 +1,13 @@ import { DebugLogger, LogFn } from '@aztec/foundation/log'; -import { deployAztecContracts } from '../utils.js'; - /** - * + * Function to execute the 'deployRollupContracts' command. + * @param rpcUrl - The RPC URL of the ethereum node. + * @param apiKey - The api key of the ethereum node endpoint. + * @param privateKey - The private key to be used in contract deployment. + * @param mnemonic - The mnemonic to be used in contract deployment. + * @param log - The log function used to print out addresses. + * @param debugLogger - The debug logger passed to original deploy function. */ export async function deployL1Contracts( rpcUrl: string, @@ -13,7 +17,12 @@ export async function deployL1Contracts( log: LogFn, debugLogger: DebugLogger, ) { - const { l1ContractAddresses } = await deployAztecContracts(rpcUrl, apiKey, privateKey, mnemonic, debugLogger); + const { createEthereumChain, deployL1Contracts: deployL1ContractOriginal } = await import('@aztec/ethereum'); + const { mnemonicToAccount, privateKeyToAccount } = await import('viem/accounts'); + + const account = !privateKey ? mnemonicToAccount(mnemonic!) : privateKeyToAccount(`0x${privateKey}`); + const chain = createEthereumChain(rpcUrl, apiKey); + const { l1ContractAddresses } = await deployL1ContractOriginal(chain.rpcUrl, account, chain.chainInfo, debugLogger); log('\n'); log(`Rollup Address: ${l1ContractAddresses.rollupAddress.toString()}`); @@ -21,5 +30,6 @@ export async function deployL1Contracts( log(`L1 -> L2 Inbox Address: ${l1ContractAddresses.inboxAddress.toString()}`); log(`L2 -> L1 Outbox address: ${l1ContractAddresses.outboxAddress.toString()}`); log(`Contract Deployment Emitter Address: ${l1ContractAddresses.contractDeploymentEmitterAddress.toString()}`); + log(`Availability Oracle Address: ${l1ContractAddresses.availabilityOracleAddress.toString()}`); log('\n'); } diff --git a/yarn-project/cli/src/utils.ts b/yarn-project/cli/src/utils.ts index 87933f75392f..fd48adcd109f 100644 --- a/yarn-project/cli/src/utils.ts +++ b/yarn-project/cli/src/utils.ts @@ -1,7 +1,7 @@ import { type ContractArtifact, type FunctionArtifact } from '@aztec/aztec.js/abi'; import { AztecAddress } from '@aztec/aztec.js/aztec_address'; import { type PXE } from '@aztec/aztec.js/interfaces/pxe'; -import { DebugLogger, LogFn } from '@aztec/foundation/log'; +import { LogFn } from '@aztec/foundation/log'; import { NoirPackageConfig } from '@aztec/foundation/noir'; import TOML from '@iarna/toml'; @@ -31,28 +31,6 @@ export function getFunctionArtifact(artifact: ContractArtifact, fnName: string): return fn; } -/** - * Function to execute the 'deployRollupContracts' command. - * @param rpcUrl - The RPC URL of the ethereum node. - * @param apiKey - The api key of the ethereum node endpoint. - * @param privateKey - The private key to be used in contract deployment. - * @param mnemonic - The mnemonic to be used in contract deployment. - */ -export async function deployAztecContracts( - rpcUrl: string, - apiKey: string, - privateKey: string, - mnemonic: string, - debugLogger: DebugLogger, -) { - const { createEthereumChain, deployL1Contracts } = await import('@aztec/ethereum'); - const { mnemonicToAccount, privateKeyToAccount } = await import('viem/accounts'); - - const account = !privateKey ? mnemonicToAccount(mnemonic!) : privateKeyToAccount(`0x${privateKey}`); - const chain = createEthereumChain(rpcUrl, apiKey); - return await deployL1Contracts(chain.rpcUrl, account, chain.chainInfo, debugLogger); -} - /** * Gets all contracts available in \@aztec/noir-contracts. * @returns The contract ABIs. diff --git a/yarn-project/ethereum/tsconfig.json b/yarn-project/ethereum/tsconfig.json index e92b3fa25626..b12e902b9463 100644 --- a/yarn-project/ethereum/tsconfig.json +++ b/yarn-project/ethereum/tsconfig.json @@ -9,6 +9,9 @@ "references": [ { "path": "../foundation" + }, + { + "path": "../l1-artifacts" } ] } From 4df8e22dd0dd74d4afc55958a0bf1c0c594a8170 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 18 Jan 2024 16:03:08 +0000 Subject: [PATCH 17/22] cleaning up deps --- yarn-project/aztec-node/package.json | 1 - yarn-project/aztec-node/tsconfig.json | 3 --- yarn-project/aztec-sandbox/package.json | 1 - yarn-project/aztec-sandbox/tsconfig.json | 3 --- yarn-project/cli/package.json | 1 - yarn-project/cli/tsconfig.json | 3 --- 6 files changed, 12 deletions(-) diff --git a/yarn-project/aztec-node/package.json b/yarn-project/aztec-node/package.json index a2e602a03fff..991f378f57e7 100644 --- a/yarn-project/aztec-node/package.json +++ b/yarn-project/aztec-node/package.json @@ -39,7 +39,6 @@ "@aztec/ethereum": "workspace:^", "@aztec/foundation": "workspace:^", "@aztec/kv-store": "workspace:^", - "@aztec/l1-artifacts": "workspace:^", "@aztec/merkle-tree": "workspace:^", "@aztec/p2p": "workspace:^", "@aztec/sequencer-client": "workspace:^", diff --git a/yarn-project/aztec-node/tsconfig.json b/yarn-project/aztec-node/tsconfig.json index 9979b01f137a..47545e975009 100644 --- a/yarn-project/aztec-node/tsconfig.json +++ b/yarn-project/aztec-node/tsconfig.json @@ -24,9 +24,6 @@ { "path": "../kv-store" }, - { - "path": "../l1-artifacts" - }, { "path": "../merkle-tree" }, diff --git a/yarn-project/aztec-sandbox/package.json b/yarn-project/aztec-sandbox/package.json index 30d0f41da34d..83a274f8fbdf 100644 --- a/yarn-project/aztec-sandbox/package.json +++ b/yarn-project/aztec-sandbox/package.json @@ -34,7 +34,6 @@ "@aztec/circuits.js": "workspace:^", "@aztec/ethereum": "workspace:^", "@aztec/foundation": "workspace:^", - "@aztec/l1-artifacts": "workspace:^", "@aztec/noir-compiler": "workspace:^", "@aztec/noir-contracts": "workspace:^", "@aztec/p2p": "workspace:^", diff --git a/yarn-project/aztec-sandbox/tsconfig.json b/yarn-project/aztec-sandbox/tsconfig.json index 7b9c2ea9188d..7c81d796b3da 100644 --- a/yarn-project/aztec-sandbox/tsconfig.json +++ b/yarn-project/aztec-sandbox/tsconfig.json @@ -27,9 +27,6 @@ { "path": "../foundation" }, - { - "path": "../l1-artifacts" - }, { "path": "../noir-compiler" }, diff --git a/yarn-project/cli/package.json b/yarn-project/cli/package.json index 25d262383576..364a14d8c02f 100644 --- a/yarn-project/cli/package.json +++ b/yarn-project/cli/package.json @@ -39,7 +39,6 @@ "@aztec/circuit-types": "workspace:^", "@aztec/ethereum": "workspace:^", "@aztec/foundation": "workspace:^", - "@aztec/l1-artifacts": "workspace:^", "@aztec/noir-compiler": "workspace:^", "@aztec/noir-contracts": "workspace:^", "@aztec/types": "workspace:^", diff --git a/yarn-project/cli/tsconfig.json b/yarn-project/cli/tsconfig.json index d90429154452..d00ac690eed9 100644 --- a/yarn-project/cli/tsconfig.json +++ b/yarn-project/cli/tsconfig.json @@ -21,9 +21,6 @@ { "path": "../foundation" }, - { - "path": "../l1-artifacts" - }, { "path": "../noir-compiler" }, From 30201d55383c70514f91bd4c6249d59c7196df56 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 19 Jan 2024 09:24:26 +0000 Subject: [PATCH 18/22] updated yarn.lock --- yarn-project/yarn.lock | 3 --- 1 file changed, 3 deletions(-) diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index 1d7706ccef95..6b3a53d6a9a0 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -170,7 +170,6 @@ __metadata: "@aztec/ethereum": "workspace:^" "@aztec/foundation": "workspace:^" "@aztec/kv-store": "workspace:^" - "@aztec/l1-artifacts": "workspace:^" "@aztec/merkle-tree": "workspace:^" "@aztec/p2p": "workspace:^" "@aztec/sequencer-client": "workspace:^" @@ -208,7 +207,6 @@ __metadata: "@aztec/circuits.js": "workspace:^" "@aztec/ethereum": "workspace:^" "@aztec/foundation": "workspace:^" - "@aztec/l1-artifacts": "workspace:^" "@aztec/noir-compiler": "workspace:^" "@aztec/noir-contracts": "workspace:^" "@aztec/p2p": "workspace:^" @@ -348,7 +346,6 @@ __metadata: "@aztec/circuit-types": "workspace:^" "@aztec/ethereum": "workspace:^" "@aztec/foundation": "workspace:^" - "@aztec/l1-artifacts": "workspace:^" "@aztec/noir-compiler": "workspace:^" "@aztec/noir-contracts": "workspace:^" "@aztec/types": "workspace:^" From 055a4ce861616033b78338448bc3925879429831 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 19 Jan 2024 09:31:23 +0000 Subject: [PATCH 19/22] fix --- .../end-to-end/src/integration_l1_publisher.test.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts index 302dba682071..3c94f0f43f30 100644 --- a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts +++ b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts @@ -104,12 +104,12 @@ describe('L1Publisher integration', () => { beforeEach(async () => { deployerAccount = privateKeyToAccount(deployerPK); - const { walletClient, publicClient, l1ContractAddresses } = await deployL1Contracts( - config.rpcUrl, - deployerAccount, - localAnvil, - logger, - ); + const { + walletClient, + publicClient: publicClient_, + l1ContractAddresses, + } = await deployL1Contracts(config.rpcUrl, deployerAccount, localAnvil, logger); + publicClient = publicClient_; rollupAddress = getAddress(l1ContractAddresses.rollupAddress.toString()); inboxAddress = getAddress(l1ContractAddresses.inboxAddress.toString()); From f1bd2f500e6a1a2fecd600fb2db37995c371b9cd Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 19 Jan 2024 09:44:34 +0000 Subject: [PATCH 20/22] formatting --- yarn-project/ethereum/src/deploy_l1_contracts.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn-project/ethereum/src/deploy_l1_contracts.ts b/yarn-project/ethereum/src/deploy_l1_contracts.ts index c098f20d1a66..b26b84f3031b 100644 --- a/yarn-project/ethereum/src/deploy_l1_contracts.ts +++ b/yarn-project/ethereum/src/deploy_l1_contracts.ts @@ -113,9 +113,9 @@ export const deployL1Contracts = async ( ); logger(`Deployed AvailabilityOracle at ${availabilityOracleAddress}`); - const rollupAddress = await deployL1Contract(walletClient, publicClient, RollupAbi, RollupBytecode, [ - getAddress(registryAddress.toString()), getAddress(availabilityOracleAddress.toString()), + getAddress(registryAddress.toString()), + getAddress(availabilityOracleAddress.toString()), ]); logger(`Deployed Rollup at ${rollupAddress}`); From 06551738fbef0fffb6f8ba088fa95204d22cca0d Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 19 Jan 2024 10:05:39 +0000 Subject: [PATCH 21/22] boxes fix --- boxes/package.json | 1 + boxes/yarn.lock | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/boxes/package.json b/boxes/package.json index 9b0417032dee..a8e1c4ed9a96 100644 --- a/boxes/package.json +++ b/boxes/package.json @@ -19,6 +19,7 @@ "@aztec/bb.js": "portal:../barretenberg/ts", "@aztec/circuit-types": "portal:../yarn-project/circuit-types", "@aztec/ethereum": "portal:../yarn-project/ethereum", + "@aztec/l1-artifacts": "portal:../yarn-project/l1-artifacts", "@aztec/types": "portal:../yarn-project/types" } } diff --git a/boxes/yarn.lock b/boxes/yarn.lock index 5719e430a8d2..f8fd0466acd6 100644 --- a/boxes/yarn.lock +++ b/boxes/yarn.lock @@ -255,7 +255,6 @@ __metadata: "@aztec/foundation": "workspace:^" eslint: "npm:^8.35.0" lodash.chunk: "npm:^4.2.0" - lodash.times: "npm:^4.3.2" tslib: "npm:^2.4.0" languageName: node linkType: soft @@ -265,6 +264,7 @@ __metadata: resolution: "@aztec/ethereum@portal:../yarn-project/ethereum::locator=%40aztec%2Fboxes%40workspace%3A." dependencies: "@aztec/foundation": "workspace:^" + "@aztec/l1-artifacts": "workspace:^" dotenv: "npm:^16.0.3" tslib: "npm:^2.4.0" viem: "npm:^1.2.5" @@ -297,11 +297,20 @@ __metadata: languageName: node linkType: soft +"@aztec/l1-artifacts@portal:../yarn-project/l1-artifacts::locator=%40aztec%2Fboxes%40workspace%3A.": + version: 0.0.0-use.local + resolution: "@aztec/l1-artifacts@portal:../yarn-project/l1-artifacts::locator=%40aztec%2Fboxes%40workspace%3A." + dependencies: + tslib: "npm:^2.4.0" + languageName: node + linkType: soft + "@aztec/types@portal:../yarn-project/types::locator=%40aztec%2Fboxes%40workspace%3A.": version: 0.0.0-use.local resolution: "@aztec/types@portal:../yarn-project/types::locator=%40aztec%2Fboxes%40workspace%3A." dependencies: "@aztec/ethereum": "workspace:^" + "@aztec/foundation": "workspace:^" languageName: node linkType: soft From 3a56cea1763ff84aa99961618d2fa4c58b5763e1 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 19 Jan 2024 11:09:17 +0000 Subject: [PATCH 22/22] formatting fix --- yarn-project/cli/src/utils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/yarn-project/cli/src/utils.ts b/yarn-project/cli/src/utils.ts index 0783cb64e002..fd48adcd109f 100644 --- a/yarn-project/cli/src/utils.ts +++ b/yarn-project/cli/src/utils.ts @@ -3,7 +3,6 @@ import { AztecAddress } from '@aztec/aztec.js/aztec_address'; import { type PXE } from '@aztec/aztec.js/interfaces/pxe'; import { LogFn } from '@aztec/foundation/log'; import { NoirPackageConfig } from '@aztec/foundation/noir'; -import { AvailabilityOracleAbi, AvailabilityOracleBytecode } from '@aztec/l1-artifacts'; import TOML from '@iarna/toml'; import { CommanderError, InvalidArgumentError } from 'commander';