diff --git a/l1-contracts/src/core/Rollup.sol b/l1-contracts/src/core/Rollup.sol index 4d6b7f197e0..bd6cbe0246a 100644 --- a/l1-contracts/src/core/Rollup.sol +++ b/l1-contracts/src/core/Rollup.sol @@ -229,6 +229,9 @@ contract Rollup is Leonidas, IRollup, ITestRollup { SignatureLib.Signature[] memory _signatures, bytes calldata _body ) external override(IRollup) { + if (_canPrune()) { + _prune(); + } bytes32 txsEffectsHash = TxsDecoder.decode(_body); // Decode and validate header @@ -313,6 +316,9 @@ contract Rollup is Leonidas, IRollup, ITestRollup { bytes calldata _aggregationObject, bytes calldata _proof ) external override(IRollup) { + if (_canPrune()) { + _prune(); + } HeaderLib.Header memory header = HeaderLib.decode(_header); if (header.globalVariables.blockNumber > tips.pendingBlockNumber) { @@ -576,7 +582,10 @@ contract Rollup is Leonidas, IRollup, ITestRollup { } function _canPrune() internal view returns (bool) { - if (tips.pendingBlockNumber == tips.provenBlockNumber) { + if ( + tips.pendingBlockNumber == tips.provenBlockNumber + || tips.pendingBlockNumber <= assumeProvenThroughBlockNumber + ) { return false; } diff --git a/l1-contracts/test/Rollup.t.sol b/l1-contracts/test/Rollup.t.sol index 4ffa3e11801..27e20595c59 100644 --- a/l1-contracts/test/Rollup.t.sol +++ b/l1-contracts/test/Rollup.t.sol @@ -455,6 +455,15 @@ contract RollupTest is DecoderBase { assertNotEq(minHeightEmpty, minHeightMixed, "Invalid min height"); } + function testPruneDuringPropose() public setUpFor("mixed_block_1") { + _testBlock("mixed_block_1", false); + warpToL2Slot(Constants.AZTEC_EPOCH_DURATION * 2); + _testBlock("mixed_block_1", false, Constants.AZTEC_EPOCH_DURATION * 2); + + assertEq(rollup.getPendingBlockNumber(), 1, "Invalid pending block number"); + assertEq(rollup.getProvenBlockNumber(), 0, "Invalid proven block number"); + } + function testBlockFee() public setUpFor("mixed_block_1") { uint256 feeAmount = 2e18; diff --git a/yarn-project/end-to-end/src/e2e_cheat_codes.test.ts b/yarn-project/end-to-end/src/e2e_cheat_codes.test.ts index 27d7124d6c5..86d78c83674 100644 --- a/yarn-project/end-to-end/src/e2e_cheat_codes.test.ts +++ b/yarn-project/end-to-end/src/e2e_cheat_codes.test.ts @@ -9,9 +9,20 @@ import { type Wallet, computeSecretHash, } from '@aztec/aztec.js'; +import { RollupAbi } from '@aztec/l1-artifacts'; import { TokenContract } from '@aztec/noir-contracts.js'; -import { type Account, type Chain, type HttpTransport, type PublicClient, type WalletClient, parseEther } from 'viem'; +import { + type Account, + type Chain, + type GetContractReturnType, + type HttpTransport, + type PublicClient, + type WalletClient, + getContract, + parseEther, +} from 'viem'; +import type * as chains from 'viem/chains'; import { setup } from './fixtures/utils.js'; @@ -22,6 +33,7 @@ describe('e2e_cheat_codes', () => { let pxe: PXE; let teardown: () => Promise; + let rollup: GetContractReturnType>; let walletClient: WalletClient; let publicClient: PublicClient; let token: TokenContract; @@ -34,9 +46,19 @@ describe('e2e_cheat_codes', () => { publicClient = deployL1ContractsValues.publicClient; admin = wallet.getCompleteAddress(); + rollup = getContract({ + address: deployL1ContractsValues.l1ContractAddresses.rollupAddress.toString(), + abi: RollupAbi, + client: deployL1ContractsValues.walletClient, + }); + token = await TokenContract.deploy(wallet, admin, 'TokenName', 'TokenSymbol', 18).send().deployed(); }); + beforeEach(async () => { + await rollup.write.setAssumeProvenThroughBlockNumber([(await rollup.read.getPendingBlockNumber()) + 1n]); + }); + afterAll(() => teardown()); describe('L1 cheatcodes', () => { diff --git a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts index 821d30fdd8c..9938cc6470b 100644 --- a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts @@ -11,7 +11,7 @@ import { import { RollupAbi } from '@aztec/l1-artifacts'; import { LendingContract, PriceFeedContract, TokenContract } from '@aztec/noir-contracts.js'; -import { jest } from '@jest/globals'; +import { afterAll, jest } from '@jest/globals'; import { getContract } from 'viem'; import { publicDeployAccounts, setup } from './fixtures/utils.js'; @@ -71,7 +71,7 @@ describe('e2e_lending_contract', () => { const rollup = getContract({ address: deployL1ContractsValues.l1ContractAddresses.rollupAddress.toString(), abi: RollupAbi, - client: deployL1ContractsValues.publicClient, + client: deployL1ContractsValues.walletClient, }); lendingAccount = new LendingAccount(wallet.getAddress(), new Fr(42)); diff --git a/yarn-project/end-to-end/src/simulators/lending_simulator.ts b/yarn-project/end-to-end/src/simulators/lending_simulator.ts index 06d258bb51b..557677b5da4 100644 --- a/yarn-project/end-to-end/src/simulators/lending_simulator.ts +++ b/yarn-project/end-to-end/src/simulators/lending_simulator.ts @@ -5,7 +5,8 @@ import { pedersenHash } from '@aztec/foundation/crypto'; import { type RollupAbi } from '@aztec/l1-artifacts'; import { type LendingContract } from '@aztec/noir-contracts.js/Lending'; -import { type Chain, type GetContractReturnType, type HttpTransport, type PublicClient } from 'viem'; +import { type Account, type GetContractReturnType, type HttpTransport, type WalletClient } from 'viem'; +import type * as chains from 'viem/chains'; import { type TokenSimulator } from './token_simulator.js'; @@ -81,7 +82,7 @@ export class LendingSimulator { private account: LendingAccount, private rate: bigint, /** the rollup contract */ - public rollup: GetContractReturnType>, + public rollup: GetContractReturnType>, /** the lending contract */ public lendingContract: LendingContract, /** the collateral asset used in the lending contract */ @@ -110,6 +111,8 @@ export class LendingSimulator { // Mine ethereum blocks such that the next block will be in a new slot await this.cc.eth.warp(this.time - ETHEREUM_SLOT_DURATION); + + await this.rollup.write.setAssumeProvenThroughBlockNumber([(await this.rollup.read.getPendingBlockNumber()) + 1n]); this.accumulator = muldivDown(this.accumulator, computeMultiplier(this.rate, BigInt(timeDiff)), BASE); }