From c183292f1802ca0b6fa6ee38087448cd82600ff3 Mon Sep 17 00:00:00 2001 From: LHerskind Date: Tue, 10 Sep 2024 16:51:53 +0000 Subject: [PATCH] refactor: remove unneeded propose and da oracle --- .github/workflows/devnet-deploys.yml | 1 - docker-compose.yml | 1 - .../files/config/config-prover-env.sh | 2 - .../files/config/config-validator-env.sh | 2 - .../deploy-contracts.config-map.yaml | 2 - l1-contracts/src/core/Rollup.sol | 177 +++++++----------- .../AvailabilityOracle.sol | 32 ---- .../core/interfaces/IAvailabilityOracle.sol | 11 -- l1-contracts/src/core/interfaces/IRollup.sol | 15 +- l1-contracts/src/core/libraries/MerkleLib.sol | 10 +- l1-contracts/terraform/main.tf | 9 - l1-contracts/test/Rollup.t.sol | 38 +--- l1-contracts/test/portals/TokenPortal.t.sol | 11 +- l1-contracts/test/portals/UniswapPortal.t.sol | 11 +- l1-contracts/test/sparta/Sparta.t.sol | 19 +- .../archiver/src/archiver/archiver.test.ts | 55 +----- .../archiver/src/archiver/archiver.ts | 128 ++++--------- .../archiver/src/archiver/data_retrieval.ts | 70 ++----- .../archiver/src/archiver/eth_log_handlers.ts | 134 ++----------- yarn-project/archiver/src/index.ts | 3 +- .../aztec-node/src/aztec-node/server.test.ts | 1 - .../aztec-node/src/aztec-node/server.ts | 3 +- .../aztec.js/src/contract/contract.test.ts | 1 - .../aztec/src/cli/aztec_start_options.ts | 6 - yarn-project/aztec/src/sandbox.ts | 6 - yarn-project/aztec/terraform/node/main.tf | 4 - .../aztec/terraform/prover-node/main.tf | 1 - yarn-project/circuit-types/src/body.ts | 2 +- .../cli/src/cmds/l1/deploy_l1_contracts.ts | 1 - .../cli/src/cmds/pxe/get_node_info.ts | 1 - yarn-project/cli/src/utils/aztec.ts | 7 +- .../composed/integration_l1_publisher.test.ts | 61 ++---- .../src/fixtures/setup_l1_contracts.ts | 6 - yarn-project/end-to-end/src/fixtures/utils.ts | 6 - .../ethereum/src/deploy_l1_contracts.ts | 9 - .../ethereum/src/l1_contract_addresses.ts | 6 - yarn-project/foundation/src/config/env_var.ts | 1 - .../scripts/generate-artifacts.sh | 1 - .../src/pxe_service/test/pxe_service.test.ts | 1 - .../src/publisher/l1-publisher.test.ts | 46 ----- .../src/publisher/l1-publisher.ts | 86 ++------- .../serialization/bytecode_serialization.ts | 2 +- 42 files changed, 195 insertions(+), 794 deletions(-) delete mode 100644 l1-contracts/src/core/availability_oracle/AvailabilityOracle.sol delete mode 100644 l1-contracts/src/core/interfaces/IAvailabilityOracle.sol diff --git a/.github/workflows/devnet-deploys.yml b/.github/workflows/devnet-deploys.yml index 496f4f72833..75d0431dfda 100644 --- a/.github/workflows/devnet-deploys.yml +++ b/.github/workflows/devnet-deploys.yml @@ -546,7 +546,6 @@ jobs: echo "TF_VAR_REGISTRY_CONTRACT_ADDRESS=$(extract registryAddress)" >>$GITHUB_ENV echo "TF_VAR_INBOX_CONTRACT_ADDRESS=$(extract inboxAddress)" >>$GITHUB_ENV echo "TF_VAR_OUTBOX_CONTRACT_ADDRESS=$(extract outboxAddress)" >>$GITHUB_ENV - echo "TF_VAR_AVAILABILITY_ORACLE_CONTRACT_ADDRESS=$(extract availabilityOracleAddress)" >>$GITHUB_ENV echo "TF_VAR_FEE_JUICE_CONTRACT_ADDRESS=$(extract feeJuiceAddress)" >>$GITHUB_ENV echo "TF_VAR_FEE_JUICE_PORTAL_CONTRACT_ADDRESS=$(extract feeJuicePortalAddress)" >>$GITHUB_ENV diff --git a/docker-compose.yml b/docker-compose.yml index 9106ee66811..18ca3c48335 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -50,7 +50,6 @@ services: REGISTRY_CONTRACT_ADDRESS: "0x589a9634c1d00c62e47b3b7a790c8dc986b3d40d" INBOX_CONTRACT_ADDRESS: "0x12d9b5effc69bf5c0c29c8258c6b6fa95a08de74" OUTBOX_CONTRACT_ADDRESS: "0x3ec4b6c68a8c2ce4c78cdd465b3019b11a568d1d" - AVAILABILITY_ORACLE_CONTRACT_ADDRESS: "0x98a4089127f3f5d555656f1c9b1801342c9d6bce" FEE_JUICE_CONTRACT_ADDRESS: "0x73c43b919973711e096bfc04c9d4b3be511ffc0b" FEE_JUICE_PORTAL_CONTRACT_ADDRESS: "0xdf25b0a34dbee9f25518f7a4d63bab8b3bb3e496" ETHEREUM_HOST: diff --git a/helm-charts/aztec-network/files/config/config-prover-env.sh b/helm-charts/aztec-network/files/config/config-prover-env.sh index a4bd508a111..125ee8dca11 100644 --- a/helm-charts/aztec-network/files/config/config-prover-env.sh +++ b/helm-charts/aztec-network/files/config/config-prover-env.sh @@ -14,7 +14,6 @@ rollup_address=$(echo "$output" | grep -oP 'Rollup Address: \K0x[a-fA-F0-9]{40}' registry_address=$(echo "$output" | grep -oP 'Registry Address: \K0x[a-fA-F0-9]{40}') inbox_address=$(echo "$output" | grep -oP 'L1 -> L2 Inbox Address: \K0x[a-fA-F0-9]{40}') outbox_address=$(echo "$output" | grep -oP 'L2 -> L1 Outbox Address: \K0x[a-fA-F0-9]{40}') -availability_oracle_address=$(echo "$output" | grep -oP 'Availability Oracle Address: \K0x[a-fA-F0-9]{40}') fee_juice_address=$(echo "$output" | grep -oP 'Fee Juice Address: \K0x[a-fA-F0-9]{40}') fee_juice_portal_address=$(echo "$output" | grep -oP 'Fee Juice Portal Address: \K0x[a-fA-F0-9]{40}') @@ -26,7 +25,6 @@ export ROLLUP_CONTRACT_ADDRESS=$rollup_address export REGISTRY_CONTRACT_ADDRESS=$registry_address export INBOX_CONTRACT_ADDRESS=$inbox_address export OUTBOX_CONTRACT_ADDRESS=$outbox_address -export AVAILABILITY_ORACLE_CONTRACT_ADDRESS=$availability_oracle_address export FEE_JUICE_CONTRACT_ADDRESS=$fee_juice_address export FEE_JUICE_PORTAL_CONTRACT_ADDRESS=$fee_juice_portal_address EOF diff --git a/helm-charts/aztec-network/files/config/config-validator-env.sh b/helm-charts/aztec-network/files/config/config-validator-env.sh index e2b29694bc7..f25834ad54d 100644 --- a/helm-charts/aztec-network/files/config/config-validator-env.sh +++ b/helm-charts/aztec-network/files/config/config-validator-env.sh @@ -14,7 +14,6 @@ rollup_address=$(echo "$output" | grep -oP 'Rollup Address: \K0x[a-fA-F0-9]{40}' registry_address=$(echo "$output" | grep -oP 'Registry Address: \K0x[a-fA-F0-9]{40}') inbox_address=$(echo "$output" | grep -oP 'L1 -> L2 Inbox Address: \K0x[a-fA-F0-9]{40}') outbox_address=$(echo "$output" | grep -oP 'L2 -> L1 Outbox Address: \K0x[a-fA-F0-9]{40}') -availability_oracle_address=$(echo "$output" | grep -oP 'Availability Oracle Address: \K0x[a-fA-F0-9]{40}') fee_juice_address=$(echo "$output" | grep -oP 'Fee Juice Address: \K0x[a-fA-F0-9]{40}') fee_juice_portal_address=$(echo "$output" | grep -oP 'Fee Juice Portal Address: \K0x[a-fA-F0-9]{40}') @@ -37,7 +36,6 @@ export ROLLUP_CONTRACT_ADDRESS=$rollup_address export REGISTRY_CONTRACT_ADDRESS=$registry_address export INBOX_CONTRACT_ADDRESS=$inbox_address export OUTBOX_CONTRACT_ADDRESS=$outbox_address -export AVAILABILITY_ORACLE_CONTRACT_ADDRESS=$availability_oracle_address export FEE_JUICE_CONTRACT_ADDRESS=$fee_juice_address export FEE_JUICE_PORTAL_CONTRACT_ADDRESS=$fee_juice_portal_address export VALIDATOR_PRIVATE_KEY=$private_key diff --git a/helm-charts/aztec-network/templates/deploy-contracts.config-map.yaml b/helm-charts/aztec-network/templates/deploy-contracts.config-map.yaml index 157cb822dbd..7191a38b78f 100644 --- a/helm-charts/aztec-network/templates/deploy-contracts.config-map.yaml +++ b/helm-charts/aztec-network/templates/deploy-contracts.config-map.yaml @@ -19,7 +19,6 @@ data: registry_address=$(echo "$output" | grep -oP 'Registry Address: \K0x[a-fA-F0-9]{40}') inbox_address=$(echo "$output" | grep -oP 'L1 -> L2 Inbox Address: \K0x[a-fA-F0-9]{40}') outbox_address=$(echo "$output" | grep -oP 'L2 -> L1 Outbox Address: \K0x[a-fA-F0-9]{40}') - availability_oracle_address=$(echo "$output" | grep -oP 'Availability Oracle Address: \K0x[a-fA-F0-9]{40}') fee_juice_address=$(echo "$output" | grep -oP 'Fee Juice Address: \K0x[a-fA-F0-9]{40}') fee_juice_portal_address=$(echo "$output" | grep -oP 'Fee Juice Portal Address: \K0x[a-fA-F0-9]{40}') @@ -29,7 +28,6 @@ data: export REGISTRY_CONTRACT_ADDRESS=$registry_address export INBOX_CONTRACT_ADDRESS=$inbox_address export OUTBOX_CONTRACT_ADDRESS=$outbox_address - export AVAILABILITY_ORACLE_CONTRACT_ADDRESS=$availability_oracle_address export FEE_JUICE_CONTRACT_ADDRESS=$fee_juice_address export FEE_JUICE_PORTAL_CONTRACT_ADDRESS=$fee_juice_portal_address EOF diff --git a/l1-contracts/src/core/Rollup.sol b/l1-contracts/src/core/Rollup.sol index 4d7efa4ee38..0a21a2c5d29 100644 --- a/l1-contracts/src/core/Rollup.sol +++ b/l1-contracts/src/core/Rollup.sol @@ -4,7 +4,6 @@ pragma solidity >=0.8.18; // Interfaces import {IRollup, ITestRollup} 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"; @@ -19,6 +18,7 @@ import {MerkleLib} from "./libraries/MerkleLib.sol"; import {SignatureLib} from "./sequencer_selection/SignatureLib.sol"; import {SafeCast} from "@oz/utils/math/SafeCast.sol"; import {DataStructures} from "./libraries/DataStructures.sol"; +import {TxsDecoder} from "./libraries/decoders/TxsDecoder.sol"; // Contracts import {MockVerifier} from "../mock/MockVerifier.sol"; @@ -47,7 +47,6 @@ contract Rollup is Leonidas, IRollup, ITestRollup { uint256 public constant TIMELINESS_PROVING_IN_SLOTS = 100; IRegistry public immutable REGISTRY; - IAvailabilityOracle public immutable AVAILABILITY_ORACLE; IInbox public immutable INBOX; IOutbox public immutable OUTBOX; uint256 public immutable VERSION; @@ -73,7 +72,6 @@ contract Rollup is Leonidas, IRollup, ITestRollup { constructor( IRegistry _registry, - IAvailabilityOracle _availabilityOracle, IFeeJuicePortal _fpcJuicePortal, bytes32 _vkTreeRoot, address _ares, @@ -81,7 +79,6 @@ contract Rollup is Leonidas, IRollup, ITestRollup { ) Leonidas(_ares) { verifier = new MockVerifier(); REGISTRY = _registry; - AVAILABILITY_ORACLE = _availabilityOracle; FEE_JUICE_PORTAL = _fpcJuicePortal; INBOX = new Inbox(address(this), Constants.L1_TO_L2_MSG_SUBTREE_HEIGHT); OUTBOX = new Outbox(address(this)); @@ -171,9 +168,17 @@ contract Rollup is Leonidas, IRollup, ITestRollup { vkTreeRoot = _vkTreeRoot; } + function computeTxsEffectsHash(bytes calldata _body) + external + view + override(IRollup) + returns (bytes32) + { + return TxsDecoder.decode(_body); + } + /** - * @notice Published the body and propose the block - * @dev This should likely be purged in the future as it is a convenience method + * @notice Publishes the body and propose the block * @dev `eth_log_handlers` rely on this function * * @param _header - The L2 block header @@ -189,27 +194,55 @@ contract Rollup is Leonidas, IRollup, ITestRollup { SignatureLib.Signature[] memory _signatures, bytes calldata _body ) external override(IRollup) { - AVAILABILITY_ORACLE.publish(_body); - propose(_header, _archive, _blockHash, _signatures); - } + bytes32 txsEffectsHash = TxsDecoder.decode(_body); - /** - * @notice Published the body and propose the block - * @dev This should likely be purged in the future as it is a convenience method - * @dev `eth_log_handlers` rely on this function - * @param _header - The L2 block header - * @param _archive - A root of the archive tree after the L2 block is applied - * @param _blockHash - The poseidon2 hash of the header added to the archive tree in the rollup circuit - * @param _body - The body of the L2 block - */ - function propose( - bytes calldata _header, - bytes32 _archive, - bytes32 _blockHash, - bytes calldata _body - ) external override(IRollup) { - AVAILABILITY_ORACLE.publish(_body); - propose(_header, _archive, _blockHash); + // Decode and validate header + HeaderLib.Header memory header = HeaderLib.decode(_header); + setupEpoch(); + _validateHeader({ + _header: header, + _signatures: _signatures, + _digest: _archive, + _currentTime: block.timestamp, + _txEffectsHash: txsEffectsHash, + _flags: DataStructures.ExecutionFlags({ignoreDA: false, ignoreSignatures: false}) + }); + + blocks[pendingBlockCount++] = BlockLog({ + archive: _archive, + blockHash: _blockHash, + slotNumber: header.globalVariables.slotNumber.toUint128() + }); + + // @note The block number here will always be >=1 as the genesis block is at 0 + bytes32 inHash = INBOX.consume(header.globalVariables.blockNumber); + if (header.contentCommitment.inHash != inHash) { + revert Errors.Rollup__InvalidInHash(inHash, header.contentCommitment.inHash); + } + + // TODO(#7218): Revert to fixed height tree for outbox, currently just providing min as interim + // Min size = smallest path of the rollup tree + 1 + (uint256 min,) = MerkleLib.computeMinMaxPathLength(header.contentCommitment.numTxs); + uint256 l2ToL1TreeMinHeight = min + 1; + OUTBOX.insert( + header.globalVariables.blockNumber, header.contentCommitment.outHash, l2ToL1TreeMinHeight + ); + + emit L2BlockProposed(header.globalVariables.blockNumber); + + // Automatically flag the block as proven if we have cheated and set assumeProvenUntilBlockNumber. + if (header.globalVariables.blockNumber < assumeProvenUntilBlockNumber) { + provenBlockCount += 1; + + if (header.globalVariables.coinbase != address(0) && header.totalFees > 0) { + // @note This will currently fail if there are insufficient funds in the bridge + // which WILL happen for the old version after an upgrade where the bridge follow. + // Consider allowing a failure. See #7938. + FEE_JUICE_PORTAL.distributeFees(header.globalVariables.coinbase, header.totalFees); + } + + emit L2ProofVerified(header.globalVariables.blockNumber, "CHEAT"); + } } /** @@ -416,87 +449,11 @@ contract Rollup is Leonidas, IRollup, ITestRollup { SignatureLib.Signature[] memory _signatures, bytes32 _digest, uint256 _currentTime, + bytes32 _txsEffectsHash, DataStructures.ExecutionFlags memory _flags ) external view override(IRollup) { HeaderLib.Header memory header = HeaderLib.decode(_header); - _validateHeader(header, _signatures, _digest, _currentTime, _flags); - } - - /** - * @notice propose an incoming L2 block with signatures - * - * @param _header - The L2 block header - * @param _archive - A root of the archive tree after the L2 block is applied - * @param _blockHash - The poseidon2 hash of the header added to the archive tree in the rollup circuit - * @param _signatures - Signatures from the validators - */ - function propose( - bytes calldata _header, - bytes32 _archive, - bytes32 _blockHash, - SignatureLib.Signature[] memory _signatures - ) public override(IRollup) { - // Decode and validate header - HeaderLib.Header memory header = HeaderLib.decode(_header); - setupEpoch(); - _validateHeader({ - _header: header, - _signatures: _signatures, - _digest: _archive, - _currentTime: block.timestamp, - _flags: DataStructures.ExecutionFlags({ignoreDA: false, ignoreSignatures: false}) - }); - - blocks[pendingBlockCount++] = BlockLog({ - archive: _archive, - blockHash: _blockHash, - slotNumber: header.globalVariables.slotNumber.toUint128() - }); - - // @note The block number here will always be >=1 as the genesis block is at 0 - bytes32 inHash = INBOX.consume(header.globalVariables.blockNumber); - if (header.contentCommitment.inHash != inHash) { - revert Errors.Rollup__InvalidInHash(inHash, header.contentCommitment.inHash); - } - - // TODO(#7218): Revert to fixed height tree for outbox, currently just providing min as interim - // Min size = smallest path of the rollup tree + 1 - (uint256 min,) = MerkleLib.computeMinMaxPathLength(header.contentCommitment.numTxs); - uint256 l2ToL1TreeMinHeight = min + 1; - OUTBOX.insert( - header.globalVariables.blockNumber, header.contentCommitment.outHash, l2ToL1TreeMinHeight - ); - - emit L2BlockProposed(header.globalVariables.blockNumber); - - // Automatically flag the block as proven if we have cheated and set assumeProvenUntilBlockNumber. - if (header.globalVariables.blockNumber < assumeProvenUntilBlockNumber) { - provenBlockCount += 1; - - if (header.globalVariables.coinbase != address(0) && header.totalFees > 0) { - // @note This will currently fail if there are insufficient funds in the bridge - // which WILL happen for the old version after an upgrade where the bridge follow. - // Consider allowing a failure. See #7938. - FEE_JUICE_PORTAL.distributeFees(header.globalVariables.coinbase, header.totalFees); - } - - emit L2ProofVerified(header.globalVariables.blockNumber, "CHEAT"); - } - } - - /** - * @notice Propose a L2 block without signatures - * - * @param _header - The L2 block header - * @param _archive - A root of the archive tree after the L2 block is applied - * @param _blockHash - The poseidon2 hash of the header added to the archive tree in the rollup circuit - */ - function propose(bytes calldata _header, bytes32 _archive, bytes32 _blockHash) - public - override(IRollup) - { - SignatureLib.Signature[] memory emptySignatures = new SignatureLib.Signature[](0); - propose(_header, _archive, _blockHash, emptySignatures); + _validateHeader(header, _signatures, _digest, _currentTime, _txsEffectsHash, _flags); } /** @@ -523,9 +480,10 @@ contract Rollup is Leonidas, IRollup, ITestRollup { SignatureLib.Signature[] memory _signatures, bytes32 _digest, uint256 _currentTime, + bytes32 _txEffectsHash, DataStructures.ExecutionFlags memory _flags ) internal view { - _validateHeaderForSubmissionBase(_header, _currentTime, _flags); + _validateHeaderForSubmissionBase(_header, _currentTime, _txEffectsHash, _flags); _validateHeaderForSubmissionSequencerSelection( _header.globalVariables.slotNumber, _signatures, _digest, _currentTime, _flags ); @@ -586,7 +544,7 @@ contract Rollup is Leonidas, IRollup, ITestRollup { * - The last archive root in the header MUST match the current archive * - The slot MUST be larger than the slot of the previous block (ensures single block per slot) * - The timestamp MUST be equal to GENESIS_TIME + slot * SLOT_DURATION - * - The availability oracle MUST return true for availability of txsEffectsHash + * - The `txsEffectsHash` of the header must match the computed `_txsEffectsHash` * - This can be relaxed to happen at the time of `submitProof` instead * * @param _header - The header to validate @@ -594,6 +552,7 @@ contract Rollup is Leonidas, IRollup, ITestRollup { function _validateHeaderForSubmissionBase( HeaderLib.Header memory _header, uint256 _currentTime, + bytes32 _txsEffectsHash, DataStructures.ExecutionFlags memory _flags ) internal view { if (block.chainid != _header.globalVariables.chainId) { @@ -640,10 +599,8 @@ contract Rollup is Leonidas, IRollup, ITestRollup { revert Errors.Rollup__TimestampInFuture(_currentTime, timestamp); } - // Check if the data is available using availability oracle (change availability oracle if you want a different DA layer) - if ( - !_flags.ignoreDA && !AVAILABILITY_ORACLE.isAvailable(_header.contentCommitment.txsEffectsHash) - ) { + // Check if the data is available + if (!_flags.ignoreDA && _header.contentCommitment.txsEffectsHash != _txsEffectsHash) { revert Errors.Rollup__UnavailableTxs(_header.contentCommitment.txsEffectsHash); } } diff --git a/l1-contracts/src/core/availability_oracle/AvailabilityOracle.sol b/l1-contracts/src/core/availability_oracle/AvailabilityOracle.sol deleted file mode 100644 index 5553d5a2143..00000000000 --- a/l1-contracts/src/core/availability_oracle/AvailabilityOracle.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2024 Aztec Labs. -pragma solidity >=0.8.18; - -// Interfaces -import {IAvailabilityOracle} from "./../interfaces/IAvailabilityOracle.sol"; - -// Libraries -import {TxsDecoder} from "./../libraries/decoders/TxsDecoder.sol"; - -/** - * @title AvailabilityOracle - * @author Aztec Labs - * @notice An availability oracle that uses L1 calldata for publication - */ -contract AvailabilityOracle is IAvailabilityOracle { - mapping(bytes32 txsHash => bool available) public override(IAvailabilityOracle) isAvailable; - - /** - * @notice Publishes transactions and marks its commitment, the TxsEffectsHash, as available - * @param _body - The block body - * @return txsEffectsHash - The TxsEffectsHash - */ - function publish(bytes calldata _body) external override(IAvailabilityOracle) returns (bytes32) { - bytes32 txsEffectsHash = TxsDecoder.decode(_body); - isAvailable[txsEffectsHash] = true; - - emit TxsPublished(txsEffectsHash); - - return txsEffectsHash; - } -} diff --git a/l1-contracts/src/core/interfaces/IAvailabilityOracle.sol b/l1-contracts/src/core/interfaces/IAvailabilityOracle.sol deleted file mode 100644 index 9c5f23ab093..00000000000 --- a/l1-contracts/src/core/interfaces/IAvailabilityOracle.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2024 Aztec Labs. -pragma solidity >=0.8.18; - -interface IAvailabilityOracle { - event TxsPublished(bytes32 txsEffectsHash); - - function publish(bytes calldata _body) external returns (bytes32); - - function isAvailable(bytes32 _txsEffectsHash) external view returns (bool); -} diff --git a/l1-contracts/src/core/interfaces/IRollup.sol b/l1-contracts/src/core/interfaces/IRollup.sol index febd60047fd..8fff6e6a5bd 100644 --- a/l1-contracts/src/core/interfaces/IRollup.sol +++ b/l1-contracts/src/core/interfaces/IRollup.sol @@ -25,6 +25,7 @@ interface IRollup { SignatureLib.Signature[] memory _signatures, bytes32 _digest, uint256 _currentTime, + bytes32 _txsEffecstHash, DataStructures.ExecutionFlags memory _flags ) external view; @@ -41,19 +42,6 @@ interface IRollup { SignatureLib.Signature[] memory _signatures, bytes calldata _body ) external; - function propose( - bytes calldata _header, - bytes32 _archive, - bytes32 _blockHash, - bytes calldata _body - ) external; - function propose(bytes calldata _header, bytes32 _archive, bytes32 _blockHash) external; - function propose( - bytes calldata _header, - bytes32 _archive, - bytes32 _blockHash, - SignatureLib.Signature[] memory _signatures - ) external; function submitBlockRootProof( bytes calldata _header, @@ -77,4 +65,5 @@ interface IRollup { function archive() external view returns (bytes32); function archiveAt(uint256 _blockNumber) external view returns (bytes32); + function computeTxsEffectsHash(bytes calldata _body) external view returns (bytes32); } diff --git a/l1-contracts/src/core/libraries/MerkleLib.sol b/l1-contracts/src/core/libraries/MerkleLib.sol index 89dc020a5a2..9d3c66d7f58 100644 --- a/l1-contracts/src/core/libraries/MerkleLib.sol +++ b/l1-contracts/src/core/libraries/MerkleLib.sol @@ -59,15 +59,15 @@ library MerkleLib { * @return (min, max) - The min and max path sizes. */ function computeMinMaxPathLength(uint256 _numTxs) internal pure returns (uint256, uint256) { - uint256 numTxs = _numTxs < 2 ? 2 : _numTxs; + uint256 adjustedNumTxs = _numTxs < 2 ? 2 : _numTxs; uint256 numSubtrees = 0; uint256 currentSubtreeSize = 1; uint256 currentSubtreeHeight = 0; uint256 firstSubtreeHeight; uint256 finalSubtreeHeight; - while (numTxs != 0) { + while (adjustedNumTxs != 0) { // If size & txs == 0, the subtree doesn't exist for this number of txs - if (currentSubtreeSize & numTxs == 0) { + if (currentSubtreeSize & adjustedNumTxs == 0) { currentSubtreeSize <<= 1; currentSubtreeHeight++; continue; @@ -75,8 +75,8 @@ library MerkleLib { // Assign the smallest rightmost subtree height if (numSubtrees == 0) finalSubtreeHeight = currentSubtreeHeight; // Assign the largest leftmost subtree height - if (numTxs - currentSubtreeSize == 0) firstSubtreeHeight = currentSubtreeHeight; - numTxs -= currentSubtreeSize; + if (adjustedNumTxs == 0) firstSubtreeHeight = currentSubtreeHeight; + adjustedNumTxs -= currentSubtreeSize; currentSubtreeSize <<= 1; currentSubtreeHeight++; numSubtrees++; diff --git a/l1-contracts/terraform/main.tf b/l1-contracts/terraform/main.tf index 4b7a1877459..7b9c55131aa 100644 --- a/l1-contracts/terraform/main.tf +++ b/l1-contracts/terraform/main.tf @@ -20,15 +20,6 @@ output "rollup_contract_address" { value = var.ROLLUP_CONTRACT_ADDRESS } -variable "AVAILABILITY_ORACLE_CONTRACT_ADDRESS" { - type = string - default = "" -} - -output "availability_oracle_contract_address" { - value = var.AVAILABILITY_ORACLE_CONTRACT_ADDRESS -} - variable "REGISTRY_CONTRACT_ADDRESS" { type = string default = "" diff --git a/l1-contracts/test/Rollup.t.sol b/l1-contracts/test/Rollup.t.sol index c908099f6a0..a772efccc80 100644 --- a/l1-contracts/test/Rollup.t.sol +++ b/l1-contracts/test/Rollup.t.sol @@ -15,7 +15,7 @@ import {Rollup} from "../src/core/Rollup.sol"; import {IFeeJuicePortal} from "../src/core/interfaces/IFeeJuicePortal.sol"; import {FeeJuicePortal} from "../src/core/FeeJuicePortal.sol"; import {Leonidas} from "../src/core/sequencer_selection/Leonidas.sol"; -import {AvailabilityOracle} from "../src/core/availability_oracle/AvailabilityOracle.sol"; +import {SignatureLib} from "../src/core/sequencer_selection/SignatureLib.sol"; import {NaiveMerkle} from "./merkle/Naive.sol"; import {MerkleTestUtil} from "./merkle/TestUtil.sol"; import {PortalERC20} from "./portals/PortalERC20.sol"; @@ -37,7 +37,7 @@ contract RollupTest is DecoderBase { PortalERC20 internal portalERC20; FeeJuicePortal internal feeJuicePortal; - AvailabilityOracle internal availabilityOracle; + SignatureLib.Signature[] internal signatures; /** * @notice Set up the contracts needed for the tests with time aligned to the provided block name @@ -53,7 +53,6 @@ contract RollupTest is DecoderBase { } registry = new Registry(address(this)); - availabilityOracle = new AvailabilityOracle(); portalERC20 = new PortalERC20(); feeJuicePortal = new FeeJuicePortal(address(this)); portalERC20.mint(address(feeJuicePortal), Constants.FEE_JUICE_INITIAL_MINT); @@ -62,7 +61,6 @@ contract RollupTest is DecoderBase { ); rollup = new Rollup( registry, - availabilityOracle, IFeeJuicePortal(address(feeJuicePortal)), bytes32(0), address(this), @@ -84,14 +82,10 @@ contract RollupTest is DecoderBase { bytes32 archive = data.archive; bytes memory body = data.body; - // Progress time as necessary - vm.warp(max(block.timestamp, data.decodedHeader.globalVariables.timestamp)); - availabilityOracle.publish(body); - // We jump to the time of the block. (unless it is in the past) vm.warp(max(block.timestamp, data.decodedHeader.globalVariables.timestamp)); - rollup.propose(header, archive, bytes32(0)); + rollup.propose(header, archive, bytes32(0), signatures, body); rollup.submitBlockRootProof(header, archive, bytes32(0), "", ""); @@ -199,7 +193,6 @@ contract RollupTest is DecoderBase { assembly { mstore(add(header, add(0x20, 0x0248)), feeAmount) } - availabilityOracle.publish(body); assertEq(portalERC20.balanceOf(address(rollup)), 0, "invalid rollup balance"); @@ -213,7 +206,7 @@ contract RollupTest is DecoderBase { assertEq(coinbaseBalance, 0, "invalid initial coinbase balance"); // Assert that balance have NOT been increased by proposing the block - rollup.propose(header, archive, bytes32(0)); + rollup.propose(header, archive, bytes32(0), signatures, body); assertEq(portalERC20.balanceOf(coinbase), 0, "invalid coinbase balance"); vm.expectRevert( @@ -260,8 +253,7 @@ contract RollupTest is DecoderBase { bytes memory body = data.body; vm.warp(max(block.timestamp, data.decodedHeader.globalVariables.timestamp)); - availabilityOracle.publish(body); - rollup.propose(header, archive, bytes32(0)); + rollup.propose(header, archive, bytes32(0), signatures, body); vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__NonSequentialProving.selector)); rollup.submitBlockRootProof(header, archive, bytes32(0), "", ""); @@ -296,10 +288,8 @@ contract RollupTest is DecoderBase { mstore(add(header, add(0x20, 0x0174)), 0x420) } - availabilityOracle.publish(body); - vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidBlockNumber.selector, 1, 0x420)); - rollup.propose(header, archive, bytes32(0)); + rollup.propose(header, archive, bytes32(0), signatures, body); } function testRevertInvalidChainId() public setUpFor("empty_block_1") { @@ -313,10 +303,8 @@ contract RollupTest is DecoderBase { mstore(add(header, add(0x20, 0x0134)), 0x420) } - availabilityOracle.publish(body); - vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidChainId.selector, 31337, 0x420)); - rollup.propose(header, archive, bytes32(0)); + rollup.propose(header, archive, bytes32(0), signatures, body); } function testRevertInvalidVersion() public setUpFor("empty_block_1") { @@ -329,10 +317,8 @@ contract RollupTest is DecoderBase { mstore(add(header, add(0x20, 0x0154)), 0x420) } - availabilityOracle.publish(body); - vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidVersion.selector, 1, 0x420)); - rollup.propose(header, archive, bytes32(0)); + rollup.propose(header, archive, bytes32(0), signatures, body); } function testRevertInvalidTimestamp() public setUpFor("empty_block_1") { @@ -350,10 +336,8 @@ contract RollupTest is DecoderBase { mstore(add(header, add(0x20, 0x01b4)), badTs) } - availabilityOracle.publish(body); - vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidTimestamp.selector, realTs, badTs)); - rollup.propose(header, archive, bytes32(0)); + rollup.propose(header, archive, bytes32(0), signatures, body); } function testBlocksWithAssumeProven() public setUpFor("mixed_block_1") { @@ -452,9 +436,7 @@ contract RollupTest is DecoderBase { _populateInbox(full.populate.sender, full.populate.recipient, full.populate.l1ToL2Content); - availabilityOracle.publish(body); - - rollup.propose(header, archive, bytes32(0)); + rollup.propose(header, archive, bytes32(0), signatures, body); if (_submitProof) { uint256 pre = rollup.provenBlockCount(); diff --git a/l1-contracts/test/portals/TokenPortal.t.sol b/l1-contracts/test/portals/TokenPortal.t.sol index 6241c57880e..96104d54ddb 100644 --- a/l1-contracts/test/portals/TokenPortal.t.sol +++ b/l1-contracts/test/portals/TokenPortal.t.sol @@ -4,7 +4,6 @@ import "forge-std/Test.sol"; // Rollup Processor import {Rollup} from "../../src/core/Rollup.sol"; -import {AvailabilityOracle} from "../../src/core/availability_oracle/AvailabilityOracle.sol"; import {Constants} from "../../src/core/libraries/ConstantsGen.sol"; import {Registry} from "../../src/core/messagebridge/Registry.sol"; import {DataStructures} from "../../src/core/libraries/DataStructures.sol"; @@ -61,14 +60,8 @@ contract TokenPortalTest is Test { function setUp() public { registry = new Registry(address(this)); portalERC20 = new PortalERC20(); - rollup = new Rollup( - registry, - new AvailabilityOracle(), - IFeeJuicePortal(address(0)), - bytes32(0), - address(this), - new address[](0) - ); + rollup = + new Rollup(registry, IFeeJuicePortal(address(0)), bytes32(0), address(this), new address[](0)); inbox = rollup.INBOX(); outbox = rollup.OUTBOX(); diff --git a/l1-contracts/test/portals/UniswapPortal.t.sol b/l1-contracts/test/portals/UniswapPortal.t.sol index 06269177402..0f506b279ef 100644 --- a/l1-contracts/test/portals/UniswapPortal.t.sol +++ b/l1-contracts/test/portals/UniswapPortal.t.sol @@ -4,7 +4,6 @@ import "forge-std/Test.sol"; // Rollup Processor import {Rollup} from "../../src/core/Rollup.sol"; -import {AvailabilityOracle} from "../../src/core/availability_oracle/AvailabilityOracle.sol"; import {Registry} from "../../src/core/messagebridge/Registry.sol"; import {DataStructures} from "../../src/core/libraries/DataStructures.sol"; import {DataStructures as PortalDataStructures} from "./DataStructures.sol"; @@ -53,14 +52,8 @@ contract UniswapPortalTest is Test { vm.selectFork(forkId); registry = new Registry(address(this)); - rollup = new Rollup( - registry, - new AvailabilityOracle(), - IFeeJuicePortal(address(0)), - bytes32(0), - address(this), - new address[](0) - ); + rollup = + new Rollup(registry, IFeeJuicePortal(address(0)), bytes32(0), address(this), new address[](0)); registry.upgrade(address(rollup)); daiTokenPortal = new TokenPortal(); diff --git a/l1-contracts/test/sparta/Sparta.t.sol b/l1-contracts/test/sparta/Sparta.t.sol index a3e4eac2d2d..e165d8b7bec 100644 --- a/l1-contracts/test/sparta/Sparta.t.sol +++ b/l1-contracts/test/sparta/Sparta.t.sol @@ -15,7 +15,6 @@ import {Outbox} from "../../src/core/messagebridge/Outbox.sol"; import {Errors} from "../../src/core/libraries/Errors.sol"; import {Rollup} from "../../src/core/Rollup.sol"; import {Leonidas} from "../../src/core/sequencer_selection/Leonidas.sol"; -import {AvailabilityOracle} from "../../src/core/availability_oracle/AvailabilityOracle.sol"; import {NaiveMerkle} from "../merkle/Naive.sol"; import {MerkleTestUtil} from "../merkle/TestUtil.sol"; import {PortalERC20} from "../portals/PortalERC20.sol"; @@ -37,8 +36,6 @@ contract SpartaTest is DecoderBase { TxsDecoderHelper internal txsHelper; PortalERC20 internal portalERC20; - AvailabilityOracle internal availabilityOracle; - mapping(address validator => uint256 privateKey) internal privateKeys; SignatureLib.Signature internal emptySignature; @@ -66,15 +63,9 @@ contract SpartaTest is DecoderBase { } registry = new Registry(address(this)); - availabilityOracle = new AvailabilityOracle(); portalERC20 = new PortalERC20(); rollup = new Rollup( - registry, - availabilityOracle, - IFeeJuicePortal(address(0)), - bytes32(0), - address(this), - initialValidators + registry, IFeeJuicePortal(address(0)), bytes32(0), address(this), initialValidators ); inbox = Inbox(address(rollup.INBOX())); outbox = Outbox(address(rollup.OUTBOX())); @@ -175,8 +166,6 @@ contract SpartaTest is DecoderBase { _populateInbox(full.populate.sender, full.populate.recipient, full.populate.l1ToL2Content); - availabilityOracle.publish(body); - ree.proposer = rollup.getCurrentProposer(); ree.shouldRevert = false; @@ -219,13 +208,15 @@ contract SpartaTest is DecoderBase { } vm.prank(ree.proposer); - rollup.propose(header, archive, bytes32(0), signatures); + rollup.propose(header, archive, bytes32(0), signatures, body); if (ree.shouldRevert) { return; } } else { - rollup.propose(header, archive, bytes32(0)); + SignatureLib.Signature[] memory signatures = new SignatureLib.Signature[](0); + + rollup.propose(header, archive, bytes32(0), signatures, body); } assertEq(_expectRevert, ree.shouldRevert, "Does not match revert expectation"); diff --git a/yarn-project/archiver/src/archiver/archiver.test.ts b/yarn-project/archiver/src/archiver/archiver.test.ts index ee7f955f954..95847d27b6a 100644 --- a/yarn-project/archiver/src/archiver/archiver.test.ts +++ b/yarn-project/archiver/src/archiver/archiver.test.ts @@ -1,5 +1,4 @@ import { - type Body, EncryptedL2BlockL2Logs, EncryptedNoteL2BlockL2Logs, L2Block, @@ -9,7 +8,7 @@ import { import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; import { sleep } from '@aztec/foundation/sleep'; -import { AvailabilityOracleAbi, type InboxAbi, RollupAbi } from '@aztec/l1-artifacts'; +import { type InboxAbi, RollupAbi } from '@aztec/l1-artifacts'; import { type MockProxy, mock } from 'jest-mock-extended'; import { @@ -31,7 +30,6 @@ describe('Archiver', () => { const rollupAddress = EthAddress.ZERO; const inboxAddress = EthAddress.ZERO; const registryAddress = EthAddress.ZERO; - const availabilityOracleAddress = EthAddress.ZERO; const blockNumbers = [1, 2, 3]; let publicClient: MockProxy>; @@ -62,7 +60,6 @@ describe('Archiver', () => { archiver = new Archiver( publicClient, rollupAddress, - availabilityOracleAddress, inboxAddress, registryAddress, archiverStore, @@ -75,14 +72,12 @@ describe('Archiver', () => { const blocks = blockNumbers.map(x => L2Block.random(x, 4, x, x + 1, 2, 2)); blocks.forEach((b, i) => (b.header.globalVariables.timestamp = new Fr(now + 1000 * (i + 1)))); - const publishTxs = blocks.map(block => block.body).map(makePublishTx); const rollupTxs = blocks.map(makeRollupTx); publicClient.getBlockNumber.mockResolvedValueOnce(2500n).mockResolvedValueOnce(2600n).mockResolvedValueOnce(2700n); mockGetLogs({ messageSent: [makeMessageSentEvent(98n, 1n, 0n), makeMessageSentEvent(99n, 1n, 1n)], - txPublished: [makeTxsPublishedEvent(101n, blocks[0].body.getTxsEffectsHash())], L2BlockProposed: [makeL2BlockProposedEvent(101n, 1n)], proofVerified: [makeProofVerifiedEvent(102n, 1n, proverId)], }); @@ -94,17 +89,11 @@ describe('Archiver', () => { makeMessageSentEvent(2505n, 2n, 2n), makeMessageSentEvent(2506n, 3n, 1n), ], - txPublished: [ - makeTxsPublishedEvent(2510n, blocks[1].body.getTxsEffectsHash()), - makeTxsPublishedEvent(2520n, blocks[2].body.getTxsEffectsHash()), - ], L2BlockProposed: [makeL2BlockProposedEvent(2510n, 2n), makeL2BlockProposedEvent(2520n, 3n)], }); - publicClient.getTransaction.mockResolvedValueOnce(publishTxs[0]); publicClient.getTransaction.mockResolvedValueOnce(rollupTxs[0]); - publishTxs.slice(1).forEach(tx => publicClient.getTransaction.mockResolvedValueOnce(tx)); rollupTxs.slice(1).forEach(tx => publicClient.getTransaction.mockResolvedValueOnce(tx)); await archiver.start(false); @@ -183,7 +172,6 @@ describe('Archiver', () => { archiver = new Archiver( publicClient, rollupAddress, - availabilityOracleAddress, inboxAddress, registryAddress, archiverStore, @@ -196,7 +184,6 @@ describe('Archiver', () => { const blocks = blockNumbers.map(x => L2Block.random(x, 4, x, x + 1, 2, 2)); - const publishTxs = blocks.map(block => block.body).map(makePublishTx); const rollupTxs = blocks.map(makeRollupTx); // Here we set the current L1 block number to 102. L1 to L2 messages after this should not be read. @@ -204,16 +191,11 @@ describe('Archiver', () => { mockGetLogs({ messageSent: [makeMessageSentEvent(66n, 1n, 0n), makeMessageSentEvent(68n, 1n, 1n)], - txPublished: [ - makeTxsPublishedEvent(70n, blocks[0].body.getTxsEffectsHash()), - makeTxsPublishedEvent(80n, blocks[1].body.getTxsEffectsHash()), - ], L2BlockProposed: [makeL2BlockProposedEvent(70n, 1n), makeL2BlockProposedEvent(80n, 2n)], }); mockGetLogs({}); - publishTxs.slice(0, numL2BlocksInTest).forEach(tx => publicClient.getTransaction.mockResolvedValueOnce(tx)); rollupTxs.slice(0, numL2BlocksInTest).forEach(tx => publicClient.getTransaction.mockResolvedValueOnce(tx)); await archiver.start(false); @@ -230,13 +212,11 @@ describe('Archiver', () => { // logs should be created in order of how archiver syncs. const mockGetLogs = (logs: { messageSent?: ReturnType[]; - txPublished?: ReturnType[]; L2BlockProposed?: ReturnType[]; proofVerified?: ReturnType[]; }) => { publicClient.getLogs .mockResolvedValueOnce(logs.messageSent ?? []) - .mockResolvedValueOnce(logs.txPublished ?? []) .mockResolvedValueOnce(logs.L2BlockProposed ?? []) .mockResolvedValueOnce(logs.proofVerified ?? []); }; @@ -256,21 +236,6 @@ function makeL2BlockProposedEvent(l1BlockNum: bigint, l2BlockNum: bigint) { } as Log; } -/** - * Makes a fake TxsPublished event for testing purposes. - * @param l1BlockNum - L1 block number. - * @param txsEffectsHash - txsEffectsHash for the body. - * @returns A TxsPublished event log. - */ -function makeTxsPublishedEvent(l1BlockNum: bigint, txsEffectsHash: Buffer) { - return { - blockNumber: l1BlockNum, - args: { - txsEffectsHash: txsEffectsHash.toString('hex'), - }, - } as Log; -} - /** * Makes fake L1ToL2 MessageSent events for testing purposes. * @param l1BlockNum - L1 block number. @@ -306,27 +271,13 @@ function makeProofVerifiedEvent(l1BlockNum: bigint, l2BlockNumber: bigint, prove */ function makeRollupTx(l2Block: L2Block) { const header = toHex(l2Block.header.toBuffer()); + const body = toHex(l2Block.body.toBuffer()); const archive = toHex(l2Block.archive.root.toBuffer()); const blockHash = toHex(l2Block.header.hash().toBuffer()); const input = encodeFunctionData({ abi: RollupAbi, functionName: 'propose', - args: [header, archive, blockHash], - }); - return { input } as Transaction; -} - -/** - * Makes a fake availability oracle tx for testing purposes. - * @param blockBody - The block body posted by the simulated tx. - * @returns A fake tx with calldata that corresponds to calling publish in the Availability Oracle contract. - */ -function makePublishTx(blockBody: Body) { - const body = toHex(blockBody.toBuffer()); - const input = encodeFunctionData({ - abi: AvailabilityOracleAbi, - functionName: 'publish', - args: [body], + args: [header, archive, blockHash, [], body], }); return { input } as Transaction; } diff --git a/yarn-project/archiver/src/archiver/archiver.ts b/yarn-project/archiver/src/archiver/archiver.ts index dec28dc5228..5015c0a1e35 100644 --- a/yarn-project/archiver/src/archiver/archiver.ts +++ b/yarn-project/archiver/src/archiver/archiver.ts @@ -2,7 +2,7 @@ import { type FromLogType, type GetUnencryptedLogsResponse, type L1ToL2MessageSource, - L2Block, + type L2Block, type L2BlockL2Logs, type L2BlockSource, type L2LogsSource, @@ -46,16 +46,10 @@ import { type Chain, type HttpTransport, type PublicClient, createPublicClient, import { type ArchiverDataStore } from './archiver_store.js'; import { type ArchiverConfig } from './config.js'; -import { - retrieveBlockBodiesFromAvailabilityOracle, - retrieveBlockMetadataFromRollup, - retrieveL1ToL2Messages, - retrieveL2ProofVerifiedEvents, -} from './data_retrieval.js'; +import { retrieveBlockFromRollup, retrieveL1ToL2Messages, retrieveL2ProofVerifiedEvents } from './data_retrieval.js'; import { getL1BlockTime } from './eth_log_handlers.js'; import { ArchiverInstrumentation } from './instrumentation.js'; import { type SingletonDataRetrieval } from './structs/data_retrieval.js'; -import { type L1Published } from './structs/published.js'; /** * Helper interface to combine all sources this archiver implementation provides. @@ -86,7 +80,6 @@ export class Archiver implements ArchiveSource { constructor( private readonly publicClient: PublicClient, private readonly rollupAddress: EthAddress, - private readonly availabilityOracleAddress: EthAddress, private readonly inboxAddress: EthAddress, private readonly registryAddress: EthAddress, private readonly store: ArchiverDataStore, @@ -119,7 +112,6 @@ export class Archiver implements ArchiveSource { const archiver = new Archiver( publicClient, config.l1Contracts.rollupAddress, - config.l1Contracts.availabilityOracleAddress, config.l1Contracts.inboxAddress, config.l1Contracts.registryAddress, archiverStore, @@ -247,72 +239,26 @@ export class Archiver implements ArchiveSource { // Read all data from chain and then write to our stores at the end const nextExpectedL2BlockNum = BigInt((await this.store.getSynchedL2BlockNumber()) + 1); - this.log.debug(`Retrieving block bodies from ${blockBodiesSynchedTo + 1n} to ${currentL1BlockNumber}`); - const retrievedBlockBodies = await retrieveBlockBodiesFromAvailabilityOracle( + this.log.debug(`Retrieving blocks from ${blocksSynchedTo + 1n} to ${currentL1BlockNumber}`); + const retrievedBlocks = await retrieveBlockFromRollup( this.publicClient, - this.availabilityOracleAddress, + this.rollupAddress, blockUntilSynced, - blockBodiesSynchedTo + 1n, + blocksSynchedTo + 1n, currentL1BlockNumber, + nextExpectedL2BlockNum, ); - this.log.debug( - `Retrieved ${retrievedBlockBodies.retrievedData.length} block bodies up to L1 block ${retrievedBlockBodies.lastProcessedL1BlockNumber}`, - ); - await this.store.addBlockBodies(retrievedBlockBodies); - - // Now that we have block bodies we will retrieve block metadata and build L2 blocks from the bodies and the metadata - let retrievedBlocks: L1Published[]; - let lastProcessedL1BlockNumber: bigint; - { - // @todo @LHerskind Investigate how necessary that nextExpectedL2BlockNum really is. - // Also, I would expect it to break horribly if we have a reorg. - this.log.debug(`Retrieving block metadata from ${blocksSynchedTo + 1n} to ${currentL1BlockNumber}`); - const retrievedBlockMetadata = await retrieveBlockMetadataFromRollup( - this.publicClient, - this.rollupAddress, - blockUntilSynced, - blocksSynchedTo + 1n, - currentL1BlockNumber, - nextExpectedL2BlockNum, - ); - - const retrievedBodyHashes = retrievedBlockMetadata.map(([header]) => header.contentCommitment.txsEffectsHash); - - // @note @LHerskind We will occasionally be hitting this point BEFORE, we have actually retrieved the bodies. - // The main reason this have not been an issue earlier is because: - // i) the design previously published the body in one tx and the header in another, - // which in an anvil auto mine world mean that they are separate blocks. - // ii) We have been lucky that latency have been small enough to not matter. - const blockBodiesFromStore = await this.store.getBlockBodies(retrievedBodyHashes); + // Add the body - if (retrievedBlockMetadata.length !== blockBodiesFromStore.length) { - this.log.warn('Block headers length does not equal block bodies length'); - } - - const blocks: L1Published[] = []; - for (let i = 0; i < retrievedBlockMetadata.length; i++) { - const [header, archive, l1] = retrievedBlockMetadata[i]; - const blockBody = blockBodiesFromStore[i]; - if (blockBody) { - blocks.push({ data: new L2Block(archive, header, blockBody), l1 }); - } else { - this.log.warn(`Block body not found for block ${header.globalVariables.blockNumber.toBigInt()}.`); - } - } - - (blocks.length ? this.log.verbose : this.log.debug)( - `Retrieved ${blocks.length || 'no'} new L2 blocks between L1 blocks ${ - blocksSynchedTo + 1n - } and ${currentL1BlockNumber}.`, - ); + (retrievedBlocks.length ? this.log.verbose : this.log.debug)( + `Retrieved ${retrievedBlocks.length || 'no'} new L2 blocks between L1 blocks ${ + blocksSynchedTo + 1n + } and ${currentL1BlockNumber}.`, + ); - retrievedBlocks = blocks; - lastProcessedL1BlockNumber = - retrievedBlockMetadata.length > 0 - ? retrievedBlockMetadata[retrievedBlockMetadata.length - 1][2].blockNumber - : blocksSynchedTo; - } + const lastProcessedL1BlockNumber = + retrievedBlocks.length > 0 ? retrievedBlocks[retrievedBlocks.length - 1].l1.blockNumber : blocksSynchedTo; this.log.debug( `Processing retrieved blocks ${retrievedBlocks @@ -320,29 +266,33 @@ export class Archiver implements ArchiveSource { .join(',')} with last processed L1 block ${lastProcessedL1BlockNumber}`, ); - await Promise.all( - retrievedBlocks.map(block => { - const noteEncryptedLogs = block.data.body.noteEncryptedLogs; - const encryptedLogs = block.data.body.encryptedLogs; - const unencryptedLogs = block.data.body.unencryptedLogs; - return this.store.addLogs(noteEncryptedLogs, encryptedLogs, unencryptedLogs, block.data.number); - }), - ); + if (retrievedBlocks.length > 0) { + await Promise.all( + retrievedBlocks.map(block => { + const noteEncryptedLogs = block.data.body.noteEncryptedLogs; + const encryptedLogs = block.data.body.encryptedLogs; + const unencryptedLogs = block.data.body.unencryptedLogs; + return this.store.addLogs(noteEncryptedLogs, encryptedLogs, unencryptedLogs, block.data.number); + }), + ); - // Unroll all logs emitted during the retrieved blocks and extract any contract classes and instances from them - await Promise.all( - retrievedBlocks.map(async block => { - const blockLogs = block.data.body.txEffects - .flatMap(txEffect => (txEffect ? [txEffect.unencryptedLogs] : [])) - .flatMap(txLog => txLog.unrollLogs()); - await this.storeRegisteredContractClasses(blockLogs, block.data.number); - await this.storeDeployedContractInstances(blockLogs, block.data.number); - await this.storeBroadcastedIndividualFunctions(blockLogs, block.data.number); - }), - ); + // Unroll all logs emitted during the retrieved blocks and extract any contract classes and instances from them + await Promise.all( + retrievedBlocks.map(async block => { + const blockLogs = block.data.body.txEffects + .flatMap(txEffect => (txEffect ? [txEffect.unencryptedLogs] : [])) + .flatMap(txLog => txLog.unrollLogs()); + await this.storeRegisteredContractClasses(blockLogs, block.data.number); + await this.storeDeployedContractInstances(blockLogs, block.data.number); + await this.storeBroadcastedIndividualFunctions(blockLogs, block.data.number); + }), + ); - if (retrievedBlocks.length > 0) { const timer = new Timer(); + await this.store.addBlockBodies({ + lastProcessedL1BlockNumber: lastProcessedL1BlockNumber, + retrievedData: retrievedBlocks.map(b => b.data.body), + }); await this.store.addBlocks(retrievedBlocks); this.instrumentation.processNewBlocks( timer.ms() / retrievedBlocks.length, diff --git a/yarn-project/archiver/src/archiver/data_retrieval.ts b/yarn-project/archiver/src/archiver/data_retrieval.ts index 81aca60a783..5827296d3f1 100644 --- a/yarn-project/archiver/src/archiver/data_retrieval.ts +++ b/yarn-project/archiver/src/archiver/data_retrieval.ts @@ -1,5 +1,5 @@ -import { type Body, type InboxLeaf } from '@aztec/circuit-types'; -import { type AppendOnlyTreeSnapshot, Fr, type Header, type Proof } from '@aztec/circuits.js'; +import { type InboxLeaf, type L2Block } from '@aztec/circuit-types'; +import { Fr, type Proof } from '@aztec/circuits.js'; import { type EthAddress } from '@aztec/foundation/eth-address'; import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { RollupAbi } from '@aztec/l1-artifacts'; @@ -10,25 +10,23 @@ import { getBlockProofFromSubmitProofTx, getL2BlockProposedLogs, getMessageSentLogs, - getTxsPublishedLogs, processL2BlockProposedLogs, processMessageSentLogs, - processTxsPublishedLogs, } from './eth_log_handlers.js'; import { type DataRetrieval } from './structs/data_retrieval.js'; -import { type L1PublishedData } from './structs/published.js'; +import { type L1Published } from './structs/published.js'; /** - * Fetches new L2 block metadata (header, archive snapshot). + * Fetches new L2 blocks. * @param publicClient - The viem public client to use for transaction retrieval. * @param rollupAddress - The address of the rollup contract. * @param blockUntilSynced - If true, blocks until the archiver has fully synced. * @param searchStartBlock - The block number to use for starting the search. * @param searchEndBlock - The highest block number that we should search up to. * @param expectedNextL2BlockNum - The next L2 block number that we expect to find. - * @returns An array of tuples representing block metadata including the header, archive tree snapshot; as well as the next eth block to search from. + * @returns An array of block; as well as the next eth block to search from. */ -export async function retrieveBlockMetadataFromRollup( +export async function retrieveBlockFromRollup( publicClient: PublicClient, rollupAddress: EthAddress, blockUntilSynced: boolean, @@ -36,8 +34,8 @@ export async function retrieveBlockMetadataFromRollup( searchEndBlock: bigint, expectedNextL2BlockNum: bigint, logger: DebugLogger = createDebugLogger('aztec:archiver'), -): Promise<[Header, AppendOnlyTreeSnapshot, L1PublishedData][]> { - const retrievedBlockMetadata: [Header, AppendOnlyTreeSnapshot, L1PublishedData][] = []; +): Promise[]> { + const retrievedBlocks: L1Published[] = []; do { if (searchStartBlock > searchEndBlock) { break; @@ -57,56 +55,12 @@ export async function retrieveBlockMetadataFromRollup( `Got L2 block processed logs for ${L2BlockProposedLogs[0].blockNumber}-${lastLog.blockNumber} between ${searchStartBlock}-${searchEndBlock} L1 blocks`, ); - const newBlockMetadata = await processL2BlockProposedLogs( - publicClient, - expectedNextL2BlockNum, - L2BlockProposedLogs, - ); - retrievedBlockMetadata.push(...newBlockMetadata); + const newBlocks = await processL2BlockProposedLogs(publicClient, expectedNextL2BlockNum, L2BlockProposedLogs); + retrievedBlocks.push(...newBlocks); searchStartBlock = lastLog.blockNumber! + 1n; - expectedNextL2BlockNum += BigInt(newBlockMetadata.length); - } while (blockUntilSynced && searchStartBlock <= searchEndBlock); - return retrievedBlockMetadata; -} - -/** - * Fetches new L2 block bodies and their hashes. - * @param publicClient - The viem public client to use for transaction retrieval. - * @param availabilityOracleAddress - The address of the availability oracle contract. - * @param blockUntilSynced - If true, blocks until the archiver has fully synced. - * @param searchStartBlock - The block number to use for starting the search. - * @param searchEndBlock - The highest block number that we should search up to. - * @returns A array of L2 block bodies as well as the next eth block to search from - */ -export async function retrieveBlockBodiesFromAvailabilityOracle( - publicClient: PublicClient, - availabilityOracleAddress: EthAddress, - blockUntilSynced: boolean, - searchStartBlock: bigint, - searchEndBlock: bigint, -): Promise> { - const retrievedBlockBodies: Body[] = []; - - do { - if (searchStartBlock > searchEndBlock) { - break; - } - const l2TxsPublishedLogs = await getTxsPublishedLogs( - publicClient, - availabilityOracleAddress, - searchStartBlock, - searchEndBlock, - ); - if (l2TxsPublishedLogs.length === 0) { - break; - } - - const newBlockBodies = await processTxsPublishedLogs(publicClient, l2TxsPublishedLogs); - retrievedBlockBodies.push(...newBlockBodies.map(([body]) => body)); - searchStartBlock = l2TxsPublishedLogs[l2TxsPublishedLogs.length - 1].blockNumber + 1n; + expectedNextL2BlockNum += BigInt(newBlocks.length); } while (blockUntilSynced && searchStartBlock <= searchEndBlock); - - return { lastProcessedL1BlockNumber: searchStartBlock - 1n, retrievedData: retrievedBlockBodies }; + return retrievedBlocks; } /** diff --git a/yarn-project/archiver/src/archiver/eth_log_handlers.ts b/yarn-project/archiver/src/archiver/eth_log_handlers.ts index 990cccde1ae..f0fdf6a1075 100644 --- a/yarn-project/archiver/src/archiver/eth_log_handlers.ts +++ b/yarn-project/archiver/src/archiver/eth_log_handlers.ts @@ -1,22 +1,13 @@ -import { Body, InboxLeaf } from '@aztec/circuit-types'; +import { Body, InboxLeaf, L2Block, type ViemSignature } from '@aztec/circuit-types'; import { AppendOnlyTreeSnapshot, Header, Proof } from '@aztec/circuits.js'; import { type EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; import { numToUInt32BE } from '@aztec/foundation/serialize'; -import { AvailabilityOracleAbi, InboxAbi, RollupAbi } from '@aztec/l1-artifacts'; +import { InboxAbi, RollupAbi } from '@aztec/l1-artifacts'; -import { - type Hex, - type Log, - type PublicClient, - decodeFunctionData, - getAbiItem, - getAddress, - hexToBytes, - slice, -} from 'viem'; +import { type Hex, type Log, type PublicClient, decodeFunctionData, getAbiItem, getAddress, hexToBytes } from 'viem'; -import { type L1PublishedData } from './structs/published.js'; +import { type L1Published, type L1PublishedData } from './structs/published.js'; /** * Processes newly received MessageSent (L1 to L2) logs. @@ -39,25 +30,21 @@ export function processMessageSentLogs( * @param publicClient - The viem public client to use for transaction retrieval. * @param expectedL2BlockNumber - The next expected L2 block number. * @param logs - L2BlockProposed logs. - * @returns - An array of tuples representing block metadata including the header, archive tree snapshot. + * @returns - An array blocks. */ export async function processL2BlockProposedLogs( publicClient: PublicClient, expectedL2BlockNumber: bigint, logs: Log[], -): Promise<[Header, AppendOnlyTreeSnapshot, L1PublishedData][]> { - const retrievedBlockMetadata: [Header, AppendOnlyTreeSnapshot, L1PublishedData][] = []; +): Promise[]> { + const retrievedBlocks: L1Published[] = []; for (const log of logs) { const blockNum = log.args.blockNumber; if (blockNum !== expectedL2BlockNumber) { throw new Error('Block number mismatch. Expected: ' + expectedL2BlockNumber + ' but got: ' + blockNum + '.'); } // TODO: Fetch blocks from calldata in parallel - const [header, archive] = await getBlockMetadataFromRollupTx( - publicClient, - log.transactionHash!, - log.args.blockNumber, - ); + const block = await getBlockFromRollupTx(publicClient, log.transactionHash!, log.args.blockNumber); const l1: L1PublishedData = { blockNumber: log.blockNumber, @@ -65,11 +52,11 @@ export async function processL2BlockProposedLogs( timestamp: await getL1BlockTime(publicClient, log.blockNumber), }; - retrievedBlockMetadata.push([header, archive, l1]); + retrievedBlocks.push({ data: block, l1 }); expectedL2BlockNumber++; } - return retrievedBlockMetadata; + return retrievedBlocks; } export async function getL1BlockTime(publicClient: PublicClient, blockNumber: bigint): Promise { @@ -77,33 +64,20 @@ export async function getL1BlockTime(publicClient: PublicClient, blockNumber: bi return block.timestamp; } -export async function processTxsPublishedLogs( - publicClient: PublicClient, - logs: Log[], -): Promise<[Body, Buffer][]> { - const retrievedBlockBodies: [Body, Buffer][] = []; - for (const log of logs) { - const newBlockBody = await getBlockBodiesFromAvailabilityOracleTx(publicClient, log.transactionHash!); - retrievedBlockBodies.push([newBlockBody, Buffer.from(hexToBytes(log.args.txsEffectsHash))]); - } - - return retrievedBlockBodies; -} - /** - * Gets block metadata (header and archive snapshot) from the calldata of an L1 transaction. + * Gets block from the calldata of an L1 transaction. * Assumes that the block was published from an EOA. * TODO: Add retries and error management. * @param publicClient - The viem public client to use for transaction retrieval. * @param txHash - Hash of the tx that published it. * @param l2BlockNum - L2 block number. - * @returns L2 block metadata (header and archive) from the calldata, deserialized + * @returns L2 block from the calldata, deserialized */ -async function getBlockMetadataFromRollupTx( +async function getBlockFromRollupTx( publicClient: PublicClient, txHash: `0x${string}`, l2BlockNum: bigint, -): Promise<[Header, AppendOnlyTreeSnapshot]> { +): Promise { const { input: data } = await publicClient.getTransaction({ hash: txHash }); const { functionName, args } = decodeFunctionData({ abi: RollupAbi, @@ -113,9 +87,10 @@ async function getBlockMetadataFromRollupTx( if (!(functionName === 'propose')) { throw new Error(`Unexpected method called ${functionName}`); } - const [headerHex, archiveRootHex, _] = args! as readonly [Hex, Hex, Hex]; + const [headerHex, archiveRootHex, , , bodyHex] = args! as readonly [Hex, Hex, Hex, ViemSignature[], Hex]; const header = Header.fromBuffer(Buffer.from(hexToBytes(headerHex))); + const blockBody = Body.fromBuffer(Buffer.from(hexToBytes(bodyHex))); const blockNumberFromHeader = header.globalVariables.blockNumber.toBigInt(); @@ -130,57 +105,7 @@ async function getBlockMetadataFromRollupTx( ]), ); - return [header, archive]; -} - -/** - * Gets block bodies from calldata of an L1 transaction, and deserializes them into Body objects. - * @note Assumes that the block was published using `propose` or `publish`. - * TODO: Add retries and error management. - * @param publicClient - The viem public client to use for transaction retrieval. - * @param txHash - Hash of the tx that published it. - * @returns An L2 block body from the calldata, deserialized - */ -async function getBlockBodiesFromAvailabilityOracleTx( - publicClient: PublicClient, - txHash: `0x${string}`, -): Promise { - const { input: data } = await publicClient.getTransaction({ hash: txHash }); - - // @note Use `forge inspect Rollup methodIdentifiers to get this, - // If using `forge sig` you will get an INVALID value for the case with a struct. - // [ - // "propose(bytes,bytes32,bytes32,(bool,uint8,bytes32,bytes32)[],bytes)": "08978fe9", - // "propose(bytes,bytes32,bytes32,bytes)": "81e6f472", - // "publish(bytes calldata _body)" - // ] - const DATA_INDEX = [4, 3, 0]; - const SUPPORTED_SIGS = ['0x08978fe9', '0x81e6f472', '0x7fd28346']; - - const signature = slice(data, 0, 4); - - if (!SUPPORTED_SIGS.includes(signature)) { - throw new Error(`Unexpected method called ${signature}`); - } - - if (signature === SUPPORTED_SIGS[SUPPORTED_SIGS.length - 1]) { - const { args } = decodeFunctionData({ - abi: AvailabilityOracleAbi, - data, - }); - const [bodyHex] = args! as [Hex]; - const blockBody = Body.fromBuffer(Buffer.from(hexToBytes(bodyHex))); - return blockBody; - } else { - const { args } = decodeFunctionData({ - abi: RollupAbi, - data, - }); - const index = SUPPORTED_SIGS.indexOf(signature); - const bodyHex = args![DATA_INDEX[index]] as Hex; - const blockBody = Body.fromBuffer(Buffer.from(hexToBytes(bodyHex))); - return blockBody; - } + return new L2Block(archive, header, blockBody); } /** @@ -208,31 +133,6 @@ export function getL2BlockProposedLogs( }); } -/** - * Gets relevant `TxsPublished` logs from chain. - * @param publicClient - The viem public client to use for transaction retrieval. - * @param dataAvailabilityOracleAddress - The address of the availability oracle contract. - * @param fromBlock - First block to get logs from (inclusive). - * @param toBlock - Last block to get logs from (inclusive). - * @returns An array of `TxsPublished` logs. - */ -export function getTxsPublishedLogs( - publicClient: PublicClient, - dataAvailabilityOracleAddress: EthAddress, - fromBlock: bigint, - toBlock: bigint, -): Promise[]> { - return publicClient.getLogs({ - address: getAddress(dataAvailabilityOracleAddress.toString()), - event: getAbiItem({ - abi: AvailabilityOracleAbi, - name: 'TxsPublished', - }), - fromBlock, - toBlock: toBlock + 1n, // the toBlock argument in getLogs is exclusive - }); -} - /** * Get relevant `MessageSent` logs emitted by Inbox on chain. * @param publicClient - The viem public client to use for transaction retrieval. diff --git a/yarn-project/archiver/src/index.ts b/yarn-project/archiver/src/index.ts index 37b0f6da3b6..f23f973101c 100644 --- a/yarn-project/archiver/src/index.ts +++ b/yarn-project/archiver/src/index.ts @@ -13,7 +13,7 @@ export * from './archiver/index.js'; export * from './rpc/index.js'; export * from './factory.js'; -export { retrieveL2ProofVerifiedEvents, retrieveBlockMetadataFromRollup } from './archiver/data_retrieval.js'; +export { retrieveL2ProofVerifiedEvents, retrieveBlockFromRollup } from './archiver/data_retrieval.js'; export { getL2BlockProposedLogs } from './archiver/eth_log_handlers.js'; @@ -37,7 +37,6 @@ async function main() { const archiver = new Archiver( publicClient, l1Contracts.rollupAddress, - l1Contracts.availabilityOracleAddress, l1Contracts.inboxAddress, l1Contracts.registryAddress, archiverStore, diff --git a/yarn-project/aztec-node/src/aztec-node/server.test.ts b/yarn-project/aztec-node/src/aztec-node/server.test.ts index f753431b918..7dbd162fbb9 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.test.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.test.ts @@ -69,7 +69,6 @@ describe('aztec node', () => { registryAddress: EthAddress.ZERO, inboxAddress: EthAddress.ZERO, outboxAddress: EthAddress.ZERO, - availabilityOracleAddress: EthAddress.ZERO, }, }, p2p, diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index ed438882142..be8d69c9af8 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -115,8 +115,7 @@ export class AztecNodeService implements AztecNode { `Rollup: ${config.l1Contracts.rollupAddress.toString()}\n` + `Registry: ${config.l1Contracts.registryAddress.toString()}\n` + `Inbox: ${config.l1Contracts.inboxAddress.toString()}\n` + - `Outbox: ${config.l1Contracts.outboxAddress.toString()}\n` + - `Availability Oracle: ${config.l1Contracts.availabilityOracleAddress.toString()}`; + `Outbox: ${config.l1Contracts.outboxAddress.toString()}`; this.log.info(message); } diff --git a/yarn-project/aztec.js/src/contract/contract.test.ts b/yarn-project/aztec.js/src/contract/contract.test.ts index f13bbfd954a..73076d9b456 100644 --- a/yarn-project/aztec.js/src/contract/contract.test.ts +++ b/yarn-project/aztec.js/src/contract/contract.test.ts @@ -22,7 +22,6 @@ describe('Contract Class', () => { const mockTxReceipt = { type: 'TxReceipt' } as any as TxReceipt; const mockUnconstrainedResultValue = 1; const l1Addresses: L1ContractAddresses = { - availabilityOracleAddress: EthAddress.random(), rollupAddress: EthAddress.random(), registryAddress: EthAddress.random(), inboxAddress: EthAddress.random(), diff --git a/yarn-project/aztec/src/cli/aztec_start_options.ts b/yarn-project/aztec/src/cli/aztec_start_options.ts index 953f07adcb3..4b551d2dc24 100644 --- a/yarn-project/aztec/src/cli/aztec_start_options.ts +++ b/yarn-project/aztec/src/cli/aztec_start_options.ts @@ -132,12 +132,6 @@ export const aztecStartOptions: { [key: string]: AztecStartOption[] } = { defaultValue: undefined, envVar: 'OUTBOX_CONTRACT_ADDRESS', }, - { - flag: '--availability-oracle-address ', - description: 'The deployed L1 availability oracle contract address', - defaultValue: undefined, - envVar: 'AVAILABILITY_ORACLE_CONTRACT_ADDRESS', - }, { flag: '--fee-juice-address ', description: 'The deployed L1 Fee Juice contract address', diff --git a/yarn-project/aztec/src/sandbox.ts b/yarn-project/aztec/src/sandbox.ts index 81e24a94856..200cdcbe04f 100644 --- a/yarn-project/aztec/src/sandbox.ts +++ b/yarn-project/aztec/src/sandbox.ts @@ -14,8 +14,6 @@ import { import { createDebugLogger } from '@aztec/foundation/log'; import { retryUntil } from '@aztec/foundation/retry'; import { - AvailabilityOracleAbi, - AvailabilityOracleBytecode, FeeJuicePortalAbi, FeeJuicePortalBytecode, InboxAbi, @@ -105,10 +103,6 @@ export async function deployContractsToL1( contractAbi: OutboxAbi, contractBytecode: OutboxBytecode, }, - availabilityOracle: { - contractAbi: AvailabilityOracleAbi, - contractBytecode: AvailabilityOracleBytecode, - }, rollup: { contractAbi: RollupAbi, contractBytecode: RollupBytecode, diff --git a/yarn-project/aztec/terraform/node/main.tf b/yarn-project/aztec/terraform/node/main.tf index 4d684d4ed1b..9933df21a32 100644 --- a/yarn-project/aztec/terraform/node/main.tf +++ b/yarn-project/aztec/terraform/node/main.tf @@ -315,10 +315,6 @@ resource "aws_ecs_task_definition" "aztec-node" { name = "REGISTRY_CONTRACT_ADDRESS" value = data.terraform_remote_state.l1_contracts.outputs.registry_contract_address }, - { - name = "AVAILABILITY_ORACLE_CONTRACT_ADDRESS" - value = data.terraform_remote_state.l1_contracts.outputs.availability_oracle_contract_address - }, { name = "FEE_JUICE_CONTRACT_ADDRESS" value = data.terraform_remote_state.l1_contracts.outputs.fee_juice_contract_address diff --git a/yarn-project/aztec/terraform/prover-node/main.tf b/yarn-project/aztec/terraform/prover-node/main.tf index 21bbf2fe783..a9c9a9708ca 100644 --- a/yarn-project/aztec/terraform/prover-node/main.tf +++ b/yarn-project/aztec/terraform/prover-node/main.tf @@ -273,7 +273,6 @@ resource "aws_ecs_task_definition" "aztec-prover-node" { { name = "INBOX_CONTRACT_ADDRESS", value = data.terraform_remote_state.l1_contracts.outputs.inbox_contract_address }, { name = "OUTBOX_CONTRACT_ADDRESS", value = data.terraform_remote_state.l1_contracts.outputs.outbox_contract_address }, { name = "REGISTRY_CONTRACT_ADDRESS", value = data.terraform_remote_state.l1_contracts.outputs.registry_contract_address }, - { name = "AVAILABILITY_ORACLE_CONTRACT_ADDRESS", value = data.terraform_remote_state.l1_contracts.outputs.availability_oracle_contract_address }, { name = "FEE_JUICE_CONTRACT_ADDRESS", value = data.terraform_remote_state.l1_contracts.outputs.fee_juice_contract_address }, { name = "FEE_JUICE_PORTAL_CONTRACT_ADDRESS", value = data.terraform_remote_state.l1_contracts.outputs.FEE_JUICE_PORTAL_CONTRACT_ADDRESS }, diff --git a/yarn-project/circuit-types/src/body.ts b/yarn-project/circuit-types/src/body.ts index c0e63aa43d3..21eba85c30e 100644 --- a/yarn-project/circuit-types/src/body.ts +++ b/yarn-project/circuit-types/src/body.ts @@ -48,7 +48,7 @@ export class Body { /** * Computes the transactions effects hash for the L2 block - * This hash is also computed in the `AvailabilityOracle`. + * This hash is also computed in the `TxDecoder`. * @returns The txs effects hash. */ getTxsEffectsHash() { diff --git a/yarn-project/cli/src/cmds/l1/deploy_l1_contracts.ts b/yarn-project/cli/src/cmds/l1/deploy_l1_contracts.ts index b57bae95ee9..08a4cc2cbf5 100644 --- a/yarn-project/cli/src/cmds/l1/deploy_l1_contracts.ts +++ b/yarn-project/cli/src/cmds/l1/deploy_l1_contracts.ts @@ -27,7 +27,6 @@ export async function deployL1Contracts( log(`Registry Address: ${l1ContractAddresses.registryAddress.toString()}`); log(`L1 -> L2 Inbox Address: ${l1ContractAddresses.inboxAddress.toString()}`); log(`L2 -> L1 Outbox Address: ${l1ContractAddresses.outboxAddress.toString()}`); - log(`Availability Oracle Address: ${l1ContractAddresses.availabilityOracleAddress.toString()}`); log(`Fee Juice Address: ${l1ContractAddresses.feeJuiceAddress.toString()}`); log(`Fee Juice Portal Address: ${l1ContractAddresses.feeJuicePortalAddress.toString()}`); } diff --git a/yarn-project/cli/src/cmds/pxe/get_node_info.ts b/yarn-project/cli/src/cmds/pxe/get_node_info.ts index 8128de79104..a3347f792d5 100644 --- a/yarn-project/cli/src/cmds/pxe/get_node_info.ts +++ b/yarn-project/cli/src/cmds/pxe/get_node_info.ts @@ -13,7 +13,6 @@ export async function getNodeInfo(rpcUrl: string, debugLogger: DebugLogger, log: log(` Registry Address: ${info.l1ContractAddresses.registryAddress.toString()}`); log(` L1 -> L2 Inbox Address: ${info.l1ContractAddresses.inboxAddress.toString()}`); log(` L2 -> L1 Outbox Address: ${info.l1ContractAddresses.outboxAddress.toString()}`); - log(` Availability Oracle Address: ${info.l1ContractAddresses.availabilityOracleAddress.toString()}`); log(` Fee Juice Address: ${info.l1ContractAddresses.feeJuiceAddress.toString()}`); log(` Fee Juice Portal Address: ${info.l1ContractAddresses.feeJuicePortalAddress.toString()}`); diff --git a/yarn-project/cli/src/utils/aztec.ts b/yarn-project/cli/src/utils/aztec.ts index 06f234a1207..921fd4ac56d 100644 --- a/yarn-project/cli/src/utils/aztec.ts +++ b/yarn-project/cli/src/utils/aztec.ts @@ -69,8 +69,7 @@ export async function deployAztecContracts( RegistryBytecode, RollupAbi, RollupBytecode, - AvailabilityOracleAbi, - AvailabilityOracleBytecode, + FeeJuicePortalAbi, FeeJuicePortalBytecode, PortalERC20Abi, @@ -96,10 +95,6 @@ export async function deployAztecContracts( contractAbi: OutboxAbi, contractBytecode: OutboxBytecode, }, - availabilityOracle: { - contractAbi: AvailabilityOracleAbi, - contractBytecode: AvailabilityOracleBytecode, - }, rollup: { contractAbi: RollupAbi, contractBytecode: RollupBytecode, diff --git a/yarn-project/end-to-end/src/composed/integration_l1_publisher.test.ts b/yarn-project/end-to-end/src/composed/integration_l1_publisher.test.ts index bc59c817ebc..b978ecda0a5 100644 --- a/yarn-project/end-to-end/src/composed/integration_l1_publisher.test.ts +++ b/yarn-project/end-to-end/src/composed/integration_l1_publisher.test.ts @@ -2,7 +2,6 @@ import { type ArchiveSource } from '@aztec/archiver'; import { getConfigEnvVars } from '@aztec/aztec-node'; import { AztecAddress, - Body, EthCheatCodes, Fr, GlobalVariables, @@ -38,7 +37,7 @@ import { fr, makeScopedL2ToL1Message } from '@aztec/circuits.js/testing'; import { type L1ContractAddresses, createEthereumChain } from '@aztec/ethereum'; import { makeTuple, range } from '@aztec/foundation/array'; import { openTmpStore } from '@aztec/kv-store/utils'; -import { AvailabilityOracleAbi, OutboxAbi, RollupAbi } from '@aztec/l1-artifacts'; +import { OutboxAbi, RollupAbi } from '@aztec/l1-artifacts'; import { SHA256Trunc, StandardTree } from '@aztec/merkle-tree'; import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; import { TxProver } from '@aztec/prover-client'; @@ -57,7 +56,6 @@ import { type HttpTransport, type PublicClient, type WalletClient, - decodeEventLog, encodeFunctionData, getAbiItem, getAddress, @@ -323,29 +321,6 @@ describe('L1Publisher integration', () => { return blockTicket; }; - it('Block body is correctly published to AvailabilityOracle', async () => { - const body = Body.random(); - // `sendPublishTx` function is private so I am hacking around TS here. I think it's ok for test purposes. - const txHash = await (publisher as any).sendPublishTx(body.toBuffer()); - const txReceipt = await publicClient.waitForTransactionReceipt({ - hash: txHash, - }); - - // Exactly 1 event should be emitted in the transaction - expect(txReceipt.logs.length).toBe(1); - - // We decode the event log before checking it - const txLog = txReceipt.logs[0]; - const topics = decodeEventLog({ - abi: AvailabilityOracleAbi, - data: txLog.data, - topics: txLog.topics, - }); - // Sol gives bytes32 txsHash, so we pad the ts bytes31 version - // We check that the txsHash in the TxsPublished event is as expected - expect(topics.args.txsEffectsHash).toEqual(`0x${body.getTxsEffectsHash().toString('hex').padStart(64, '0')}`); - }); - it(`Build ${numberOfConsecutiveBlocks} blocks of 4 bloated txs building on each other`, async () => { const archiveInRollup_ = await rollup.read.archive(); expect(hexStringToBuffer(archiveInRollup_.toString())).toEqual(new Fr(GENESIS_ARCHIVE_ROOT).toBuffer()); @@ -526,29 +501,17 @@ describe('L1Publisher integration', () => { hash: logs[i].transactionHash!, }); - const expectedData = - i == 0 - ? encodeFunctionData({ - abi: RollupAbi, - functionName: 'propose', - args: [ - `0x${block.header.toBuffer().toString('hex')}`, - `0x${block.archive.root.toBuffer().toString('hex')}`, - `0x${block.header.hash().toBuffer().toString('hex')}`, - [], - `0x${block.body.toBuffer().toString('hex')}`, - ], - }) - : encodeFunctionData({ - abi: RollupAbi, - functionName: 'propose', - args: [ - `0x${block.header.toBuffer().toString('hex')}`, - `0x${block.archive.root.toBuffer().toString('hex')}`, - `0x${block.header.hash().toBuffer().toString('hex')}`, - [], - ], - }); + const expectedData = encodeFunctionData({ + abi: RollupAbi, + functionName: 'propose', + args: [ + `0x${block.header.toBuffer().toString('hex')}`, + `0x${block.archive.root.toBuffer().toString('hex')}`, + `0x${block.header.hash().toBuffer().toString('hex')}`, + [], + `0x${block.body.toBuffer().toString('hex')}`, + ], + }); expect(ethTx.input).toEqual(expectedData); await progressTimeBySlot(); diff --git a/yarn-project/end-to-end/src/fixtures/setup_l1_contracts.ts b/yarn-project/end-to-end/src/fixtures/setup_l1_contracts.ts index 4cc48f528fa..62099e72a14 100644 --- a/yarn-project/end-to-end/src/fixtures/setup_l1_contracts.ts +++ b/yarn-project/end-to-end/src/fixtures/setup_l1_contracts.ts @@ -1,7 +1,5 @@ import { type DebugLogger, type L1ContractArtifactsForDeployment, deployL1Contracts } from '@aztec/aztec.js'; import { - AvailabilityOracleAbi, - AvailabilityOracleBytecode, FeeJuicePortalAbi, FeeJuicePortalBytecode, InboxAbi, @@ -41,10 +39,6 @@ export const setupL1Contracts = async ( 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 94c65a0c088..1045d838954 100644 --- a/yarn-project/end-to-end/src/fixtures/utils.ts +++ b/yarn-project/end-to-end/src/fixtures/utils.ts @@ -44,8 +44,6 @@ import { NULL_KEY, isAnvilTestChain } from '@aztec/ethereum'; import { bufferAsFields } from '@aztec/foundation/abi'; import { makeBackoff, retry, retryUntil } from '@aztec/foundation/retry'; import { - AvailabilityOracleAbi, - AvailabilityOracleBytecode, FeeJuicePortalAbi, FeeJuicePortalBytecode, InboxAbi, @@ -133,10 +131,6 @@ export const setupL1Contracts = async ( 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 eaf4f83f13b..290d0728a68 100644 --- a/yarn-project/ethereum/src/deploy_l1_contracts.ts +++ b/yarn-project/ethereum/src/deploy_l1_contracts.ts @@ -73,10 +73,6 @@ export interface L1ContractArtifactsForDeployment { * Outbox contract artifacts */ outbox: ContractArtifacts; - /** - * Availability Oracle contract artifacts - */ - availabilityOracle: ContractArtifacts; /** * Registry contract artifacts */ @@ -186,9 +182,6 @@ export const deployL1Contracts = async ( const registryAddress = await deployer.deploy(contractsToDeploy.registry, [account.address.toString()]); logger.info(`Deployed Registry at ${registryAddress}`); - const availabilityOracleAddress = await deployer.deploy(contractsToDeploy.availabilityOracle); - logger.info(`Deployed AvailabilityOracle at ${availabilityOracleAddress}`); - const feeJuiceAddress = await deployer.deploy(contractsToDeploy.feeJuice); logger.info(`Deployed Fee Juice at ${feeJuiceAddress}`); @@ -199,7 +192,6 @@ export const deployL1Contracts = async ( const rollupAddress = await deployer.deploy(contractsToDeploy.rollup, [ getAddress(registryAddress.toString()), - getAddress(availabilityOracleAddress.toString()), getAddress(feeJuicePortalAddress.toString()), args.vkTreeRoot.toString(), account.address.toString(), @@ -318,7 +310,6 @@ export const deployL1Contracts = async ( logger.verbose(`All transactions for L1 deployment have been mined`); 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 6ec61e8b24c..0230ad3d491 100644 --- a/yarn-project/ethereum/src/l1_contract_addresses.ts +++ b/yarn-project/ethereum/src/l1_contract_addresses.ts @@ -8,7 +8,6 @@ import type { DebugLogger } from '@aztec/foundation/log'; * For reference: https://github.com/AztecProtocol/aztec-packages/pull/5553 */ export const l1ContractsNames = [ - 'availabilityOracleAddress', 'rollupAddress', 'registryAddress', 'inboxAddress', @@ -27,11 +26,6 @@ export type L1ContractAddresses = { const parseEnv = (val: string) => EthAddress.fromString(val); export const l1ContractAddressesMapping: ConfigMappingsType = { - availabilityOracleAddress: { - env: 'AVAILABILITY_ORACLE_CONTRACT_ADDRESS', - description: 'The deployed L1 availability oracle contract address.', - parseEnv, - }, rollupAddress: { env: 'ROLLUP_CONTRACT_ADDRESS', description: 'The deployed L1 rollup contract address.', diff --git a/yarn-project/foundation/src/config/env_var.ts b/yarn-project/foundation/src/config/env_var.ts index ebd360bcf5a..7b01983b743 100644 --- a/yarn-project/foundation/src/config/env_var.ts +++ b/yarn-project/foundation/src/config/env_var.ts @@ -11,7 +11,6 @@ export type EnvVar = | 'REGISTRY_CONTRACT_ADDRESS' | 'INBOX_CONTRACT_ADDRESS' | 'OUTBOX_CONTRACT_ADDRESS' - | 'AVAILABILITY_ORACLE_CONTRACT_ADDRESS' | 'FEE_JUICE_CONTRACT_ADDRESS' | 'FEE_JUICE_PORTAL_CONTRACT_ADDRESS' | 'ARCHIVER_URL' diff --git a/yarn-project/l1-artifacts/scripts/generate-artifacts.sh b/yarn-project/l1-artifacts/scripts/generate-artifacts.sh index 520619a558b..1d82db63c06 100755 --- a/yarn-project/l1-artifacts/scripts/generate-artifacts.sh +++ b/yarn-project/l1-artifacts/scripts/generate-artifacts.sh @@ -10,7 +10,6 @@ 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 b8931137f01..b634eb62777 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 @@ -26,7 +26,6 @@ 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/publisher/l1-publisher.test.ts b/yarn-project/sequencer-client/src/publisher/l1-publisher.test.ts index 6722ded9101..da2a8aebe14 100644 --- a/yarn-project/sequencer-client/src/publisher/l1-publisher.test.ts +++ b/yarn-project/sequencer-client/src/publisher/l1-publisher.test.ts @@ -9,27 +9,6 @@ import { type GetTransactionReceiptReturnType, type PrivateKeyAccount } from 'vi import { type PublisherConfig, type TxSenderConfig } from './config.js'; import { L1Publisher } from './l1-publisher.js'; -interface MockAvailabilityOracleWrite { - publish: (args: readonly [`0x${string}`], options: { account: PrivateKeyAccount }) => Promise<`0x${string}`>; -} - -interface MockAvailabilityOracleEstimate { - publish: (args: readonly [`0x${string}`], options: { account: PrivateKeyAccount }) => Promise; -} - -interface MockAvailabilityOracleRead { - isAvailable: (args: readonly [`0x${string}`]) => Promise; -} - -class MockAvailabilityOracle { - constructor( - public write: MockAvailabilityOracleWrite, - public simulate: MockAvailabilityOracleWrite, - public estimateGas: MockAvailabilityOracleEstimate, - public read: MockAvailabilityOracleRead, - ) {} -} - interface MockPublicClient { getTransactionReceipt: ({ hash }: { hash: '0x${string}' }) => Promise; getBlock(): Promise<{ timestamp: bigint }>; @@ -71,12 +50,6 @@ describe('L1Publisher', () => { let rollupContractSimulate: MockProxy; let rollupContract: MockRollupContract; - let availabilityOracleRead: MockProxy; - let availabilityOracleWrite: MockProxy; - let availabilityOracleSimulate: MockProxy; - let availabilityOracleEstimate: MockProxy; - let availabilityOracle: MockAvailabilityOracle; - let publicClient: MockProxy; let processTxHash: `0x${string}`; @@ -123,17 +96,6 @@ describe('L1Publisher', () => { rollupContractRead = mock(); rollupContract = new MockRollupContract(rollupContractWrite, rollupContractSimulate, rollupContractRead); - availabilityOracleWrite = mock(); - availabilityOracleRead = mock(); - availabilityOracleSimulate = mock(); - availabilityOracleEstimate = mock(); - availabilityOracle = new MockAvailabilityOracle( - availabilityOracleWrite, - availabilityOracleSimulate, - availabilityOracleEstimate, - availabilityOracleRead, - ); - publicClient = mock(); const config = { @@ -141,7 +103,6 @@ describe('L1Publisher', () => { l1ChainId: 1, publisherPrivateKey: `0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80`, l1Contracts: { - availabilityOracleAddress: EthAddress.ZERO.toString(), rollupAddress: EthAddress.ZERO.toString(), }, l1PublishRetryIntervalMS: 1, @@ -149,14 +110,12 @@ describe('L1Publisher', () => { publisher = new L1Publisher(config, new NoopTelemetryClient()); - (publisher as any)['availabilityOracleContract'] = availabilityOracle; (publisher as any)['rollupContract'] = rollupContract; (publisher as any)['publicClient'] = publicClient; account = (publisher as any)['account']; rollupContractRead.getCurrentSlot.mockResolvedValue(l2Block.header.globalVariables.slotNumber.toBigInt()); - availabilityOracleEstimate.publish.mockResolvedValueOnce(GAS_GUESS); publicClient.getBlock.mockResolvedValue({ timestamp: 12n }); }); @@ -186,7 +145,6 @@ describe('L1Publisher', () => { }); it('publishes l2 block to l1 (already published body)', async () => { - availabilityOracleRead.isAvailable.mockResolvedValueOnce(true); rollupContractRead.archive.mockResolvedValue(l2Block.header.lastArchive.root.toString() as `0x${string}`); rollupContractWrite.propose.mockResolvedValueOnce(processTxHash); rollupContractSimulate.propose.mockResolvedValueOnce(processTxHash); @@ -206,7 +164,6 @@ describe('L1Publisher', () => { }); it('does not retry if sending a propose tx fails', async () => { - availabilityOracleRead.isAvailable.mockResolvedValueOnce(true); rollupContractRead.archive.mockResolvedValue(l2Block.header.lastArchive.root.toString() as `0x${string}`); rollupContractWrite.propose .mockRejectedValueOnce(new Error()) @@ -245,7 +202,6 @@ describe('L1Publisher', () => { }); it('retries if fetching the receipt fails (propose)', async () => { - availabilityOracleRead.isAvailable.mockResolvedValueOnce(true); rollupContractRead.archive.mockResolvedValue(l2Block.header.lastArchive.root.toString() as `0x${string}`); rollupContractSimulate.propose.mockResolvedValueOnce(processTxHash); rollupContractWrite.propose.mockResolvedValueOnce(processTxHash); @@ -280,7 +236,6 @@ describe('L1Publisher', () => { }); it('returns false if propose tx reverts', async () => { - availabilityOracleRead.isAvailable.mockResolvedValueOnce(true); rollupContractRead.archive.mockResolvedValue(l2Block.header.lastArchive.root.toString() as `0x${string}`); publicClient.getTransactionReceipt.mockResolvedValueOnce({ ...processTxReceipt, status: 'reverted' }); @@ -303,7 +258,6 @@ describe('L1Publisher', () => { }); it('returns false if sending propose tx is interrupted', async () => { - availabilityOracleRead.isAvailable.mockResolvedValueOnce(true); rollupContractRead.archive.mockResolvedValue(l2Block.header.lastArchive.root.toString() as `0x${string}`); rollupContractWrite.propose.mockImplementationOnce(() => sleep(10, processTxHash) as Promise<`0x${string}`>); diff --git a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts index 4f30bef3215..e473f95329b 100644 --- a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts +++ b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts @@ -7,7 +7,7 @@ import { createDebugLogger } from '@aztec/foundation/log'; import { serializeToBuffer } from '@aztec/foundation/serialize'; import { InterruptibleSleep } from '@aztec/foundation/sleep'; import { Timer } from '@aztec/foundation/timer'; -import { AvailabilityOracleAbi, RollupAbi } from '@aztec/l1-artifacts'; +import { RollupAbi } from '@aztec/l1-artifacts'; import { type TelemetryClient } from '@aztec/telemetry-client'; import pick from 'lodash.pick'; @@ -21,6 +21,7 @@ import { type WalletClient, createPublicClient, createWalletClient, + encodeFunctionData, getAddress, getContract, hexToBytes, @@ -103,10 +104,6 @@ export class L1Publisher { private metrics: L1PublisherMetrics; private log = createDebugLogger('aztec:sequencer:publisher'); - private availabilityOracleContract: GetContractReturnType< - typeof AvailabilityOracleAbi, - WalletClient - >; private rollupContract: GetContractReturnType< typeof RollupAbi, WalletClient @@ -135,11 +132,6 @@ export class L1Publisher { transport: http(chain.rpcUrl), }); - this.availabilityOracleContract = getContract({ - address: getAddress(l1Contracts.availabilityOracleAddress.toString()), - abi: AvailabilityOracleAbi, - client: walletClient, - }); this.rollupContract = getContract({ address: getAddress(l1Contracts.rollupAddress.toString()), abi: RollupAbi, @@ -192,6 +184,7 @@ export class L1Publisher { formattedSignatures, `0x${attestationData.digest.toString('hex')}`, ts, + `0x${header.contentCommitment.txsEffectsHash.toString('hex')}`, flags, ] as const; @@ -214,11 +207,6 @@ export class L1Publisher { return committee.map(EthAddress.fromString); } - checkIfTxsAreAvailable(block: L2Block): Promise { - const args = [`0x${block.body.getTxsEffectsHash().toString('hex').padStart(64, '0')}`] 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) { @@ -254,11 +242,8 @@ export class L1Publisher { // Publish body and propose block (if not already published) if (!this.interrupted) { - let txHash; const timer = new Timer(); - const isAvailable = await this.checkIfTxsAreAvailable(block); - // @note This will make sure that we are passing the checks for our header ASSUMING that the data is also made available // This means that we can avoid the simulation issues in later checks. // By simulation issue, I mean the fact that the block.timestamp is equal to the last block, not the next, which @@ -268,12 +253,7 @@ export class L1Publisher { signatures: attestations ?? [], }); - if (isAvailable) { - this.log.verbose(`Transaction effects of block ${block.number} already published.`, ctx); - txHash = await this.sendProposeWithoutBodyTx(processTxArgs); - } else { - txHash = await this.sendProposeTx(processTxArgs); - } + const txHash = await this.sendProposeTx(processTxArgs); if (!txHash) { this.log.info(`Failed to publish block ${block.number} to L1`, ctx); @@ -406,57 +386,19 @@ export class L1Publisher { } } - // This is used in `integration_l1_publisher.test.ts` currently. Could be removed though. - private async sendPublishTx(encodedBody: Buffer): Promise { - if (!this.interrupted) { - try { - this.log.info(`TxEffects size=${encodedBody.length} bytes`); - const args = [`0x${encodedBody.toString('hex')}`] as const; - - await this.availabilityOracleContract.simulate.publish(args, { - account: this.account, - }); - - return await this.availabilityOracleContract.write.publish(args, { - account: this.account, - }); - } catch (err) { - this.log.error(`TxEffects publish failed`, err); - return undefined; - } - } - } - - private async sendProposeWithoutBodyTx(encodedData: L1ProcessArgs): Promise { + private async sendProposeTx(encodedData: L1ProcessArgs): Promise { if (!this.interrupted) { try { - const attestations = encodedData.attestations - ? encodedData.attestations.map(attest => attest.toViemSignature()) - : []; - const args = [ - `0x${encodedData.header.toString('hex')}`, - `0x${encodedData.archive.toString('hex')}`, - `0x${encodedData.blockHash.toString('hex')}`, - attestations, - ] as const; - - return await this.rollupContract.write.propose(args, { - account: this.account, - gas: L1Publisher.PROPOSE_GAS_GUESS, + // We have to jump a few hoops because viem is not happy around estimating gas for view functions + const computeTxsEffectsHashGas = await this.publicClient.estimateGas({ + to: this.rollupContract.address, + data: encodeFunctionData({ + abi: this.rollupContract.abi, + functionName: 'computeTxsEffectsHash', + args: [`0x${encodedData.body.toString('hex')}`], + }), }); - } catch (err) { - this.log.error(`Rollup publish failed`, err); - return undefined; - } - } - } - private async sendProposeTx(encodedData: L1ProcessArgs): Promise { - if (!this.interrupted) { - try { - const publishGas = await this.availabilityOracleContract.estimateGas.publish([ - `0x${encodedData.body.toString('hex')}`, - ]); const min = (a: bigint, b: bigint) => (a > b ? b : a); // @note We perform this guesstimate instead of the usual `gasEstimate` since @@ -464,7 +406,7 @@ export class L1Publisher { // we will fail estimation in the case where we are simulating for the // first ethereum block within our slot (as current time is not in the // slot yet). - const gasGuesstimate = min(publishGas * 2n + L1Publisher.PROPOSE_GAS_GUESS, 15_000_000n); + const gasGuesstimate = min(computeTxsEffectsHashGas + L1Publisher.PROPOSE_GAS_GUESS, 15_000_000n); const attestations = encodedData.attestations ? encodedData.attestations.map(attest => attest.toViemSignature()) diff --git a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts index 099357c888d..ed0b02e0a23 100644 --- a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts +++ b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts @@ -2,7 +2,6 @@ import { PedersenCommitment } from '../opcodes/commitment.js'; import { DAGasLeft, L2GasLeft } from '../opcodes/context_getters.js'; import { EcAdd } from '../opcodes/ec_add.js'; import { Keccak, KeccakF1600, Pedersen, Poseidon2, Sha256 } from '../opcodes/hashing.js'; -import { Instruction } from '../opcodes/index.js'; import { Add, Address, @@ -24,6 +23,7 @@ import { FieldDiv, FunctionSelector, GetContractInstance, + Instruction, InternalCall, InternalReturn, Jump,