Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Remove proof from L1 Rollup process #7347

Merged
merged 7 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 34 additions & 29 deletions l1-contracts/src/core/Rollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,8 @@ contract Rollup is IRollup {
* @notice Process an incoming L2 block and progress the state
* @param _header - The L2 block header
* @param _archive - A root of the archive tree after the L2 block is applied
* @param _proof - The proof of correct execution
*/
function process(
bytes calldata _header,
bytes32 _archive,
bytes calldata _aggregationObject,
bytes calldata _proof
) external override(IRollup) {
function process(bytes calldata _header, bytes32 _archive) external override(IRollup) {
// Decode and validate header
HeaderLib.Header memory header = HeaderLib.decode(_header);
HeaderLib.validate(header, VERSION, lastBlockTs, archive);
Expand All @@ -124,6 +118,38 @@ contract Rollup is IRollup {
revert Errors.Rollup__InvalidSequencer(msg.sender);
}

archive = _archive;
lastBlockTs = block.timestamp;

bytes32 inHash = INBOX.consume();
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
);

// pay the coinbase 1 gas token if it is not empty and header.totalFees is not zero
if (header.globalVariables.coinbase != address(0) && header.totalFees > 0) {
GAS_TOKEN.transfer(address(header.globalVariables.coinbase), header.totalFees);
}
Comment on lines +133 to +140
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, shouldn't this go out only after the block is proven (to avoid the block being reverted due to missing proof)? If that's the case, I'd add a note/todo about it

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's one of the items I got on the design doc, yep. Fee payment will have to change quite a lot.


emit L2BlockProcessed(header.globalVariables.blockNumber);
}

function submitProof(
bytes calldata _header,
bytes32 _archive,
bytes calldata _aggregationObject,
bytes calldata _proof
) external override(IRollup) {
HeaderLib.Header memory header = HeaderLib.decode(_header);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think submitProof should also verify the block it's verifying is available on L1 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, submitProof is missing a lot of checks. I just wanted to get something working for now.


bytes32[] memory publicInputs =
new bytes32[](3 + Constants.HEADER_LENGTH + Constants.AGGREGATION_OBJECT_LENGTH);
// the archive tree root
Expand Down Expand Up @@ -156,28 +182,7 @@ contract Rollup is IRollup {
revert Errors.Rollup__InvalidProof();
}

archive = _archive;
lastBlockTs = block.timestamp;

bytes32 inHash = INBOX.consume();
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
);

// pay the coinbase 1 gas token if it is not empty and header.totalFees is not zero
if (header.globalVariables.coinbase != address(0) && header.totalFees > 0) {
GAS_TOKEN.transfer(address(header.globalVariables.coinbase), header.totalFees);
}

emit L2BlockProcessed(header.globalVariables.blockNumber);
emit L2ProofVerified(header.globalVariables.blockNumber);
}

function _computePublicInputHash(bytes calldata _header, bytes32 _archive)
Expand Down
7 changes: 5 additions & 2 deletions l1-contracts/src/core/interfaces/IRollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ pragma solidity >=0.8.18;

interface IRollup {
event L2BlockProcessed(uint256 indexed blockNumber);
event L2ProofVerified(uint256 indexed blockNumber);

function process(
function process(bytes calldata _header, bytes32 _archive) external;

function submitProof(
bytes calldata _header,
bytes32 _archive,
bytes calldata _aggregationObject,
bytes memory _proof
bytes calldata _proof
) external;

function setVerifier(address _verifier) external;
Expand Down
10 changes: 5 additions & 5 deletions l1-contracts/test/Rollup.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ contract RollupTest is DecoderBase {
availabilityOracle.publish(body);

vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidChainId.selector, 0x420, 31337));
rollup.process(header, archive, bytes(""), bytes(""));
rollup.process(header, archive);
}

function testRevertInvalidVersion() public {
Expand All @@ -101,7 +101,7 @@ contract RollupTest is DecoderBase {
availabilityOracle.publish(body);

vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidVersion.selector, 0x420, 1));
rollup.process(header, archive, bytes(""), bytes(""));
rollup.process(header, archive);
}

function testRevertTimestampInFuture() public {
Expand All @@ -118,7 +118,7 @@ contract RollupTest is DecoderBase {
availabilityOracle.publish(body);

vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__TimestampInFuture.selector));
rollup.process(header, archive, bytes(""), bytes(""));
rollup.process(header, archive);
}

function testRevertTimestampTooOld() public {
Expand All @@ -133,7 +133,7 @@ contract RollupTest is DecoderBase {
availabilityOracle.publish(body);

vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__TimestampTooOld.selector));
rollup.process(header, archive, bytes(""), bytes(""));
rollup.process(header, archive);
}

function _testBlock(string memory name) public {
Expand All @@ -153,7 +153,7 @@ contract RollupTest is DecoderBase {
uint256 toConsume = inbox.toConsume();

vm.record();
rollup.process(header, archive, bytes(""), bytes(""));
rollup.process(header, archive);

assertEq(inbox.toConsume(), toConsume + 1, "Message subtree not consumed");

Expand Down
9 changes: 2 additions & 7 deletions yarn-project/accounts/package.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,5 @@
"build:ts": "tsc -b",
"clean": "rm -rf ./dest .tsbuildinfo ./artifacts"
},
"files": [
"dest",
"src",
"artifacts",
"!*.test.*"
]
}
"files": ["dest", "src", "artifacts", "!*.test.*"]
}
4 changes: 1 addition & 3 deletions yarn-project/archiver/src/archiver/archiver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,12 +248,10 @@ function makeMessageSentEvent(l1BlockNum: bigint, l2BlockNumber: bigint, index:
function makeRollupTx(l2Block: L2Block) {
const header = toHex(l2Block.header.toBuffer());
const archive = toHex(l2Block.archive.root.toBuffer());
const aggregationObject = `0x`;
const proof = `0x`;
const input = encodeFunctionData({
abi: RollupAbi,
functionName: 'process',
args: [header, archive, aggregationObject, proof],
args: [header, archive],
});
return { input } as Transaction<bigint, number>;
}
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/archiver/src/archiver/eth_log_handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ async function getBlockMetadataFromRollupTx(
if (functionName !== 'process') {
throw new Error(`Unexpected method called ${functionName}`);
}
const [headerHex, archiveRootHex] = args! as readonly [Hex, Hex, Hex, Hex];
const [headerHex, archiveRootHex] = args! as readonly [Hex, Hex];

const header = Header.fromBuffer(Buffer.from(hexToBytes(headerHex)));

Expand Down
22 changes: 17 additions & 5 deletions yarn-project/circuit-types/src/stats/stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,8 @@ export type L2BlockStats = {
unencryptedLogSize?: number;
};

/** Stats logged for each L1 rollup publish tx.*/
/** Stats logged for each L1 publish tx.*/
export type L1PublishStats = {
/** Name of the event for metrics purposes */
eventName: 'rollup-published-to-l1';
/** Effective gas price of the tx. */
gasPrice: bigint;
/** Effective gas used in the tx. */
Expand All @@ -40,7 +38,20 @@ export type L1PublishStats = {
calldataGas: number;
/** Size in bytes of the calldata. */
calldataSize: number;
} & L2BlockStats;
};

/** Stats logged for each L1 rollup publish tx.*/
export type L1PublishBlockStats = {
/** Name of the event for metrics purposes */
eventName: 'rollup-published-to-l1';
} & L1PublishStats &
L2BlockStats;

/** Stats logged for each L1 rollup publish tx.*/
export type L1PublishProofStats = {
/** Name of the event for metrics purposes */
eventName: 'proof-published-to-l1';
} & L1PublishStats;

/** Stats logged for synching node chain history. */
export type NodeSyncedChainHistoryStats = {
Expand Down Expand Up @@ -271,7 +282,8 @@ export type Stats =
| CircuitSimulationStats
| CircuitWitnessGenerationStats
| PublicDBAccessStats
| L1PublishStats
| L1PublishBlockStats
| L1PublishProofStats
| L2BlockBuiltStats
| L2BlockHandledStats
| NodeSyncedChainHistoryStats
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ import {
MAX_NULLIFIERS_PER_TX,
MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
type Proof,
PublicDataUpdateRequest,
makeEmptyProof,
} from '@aztec/circuits.js';
import { fr, makeProof } from '@aztec/circuits.js/testing';
import { type L1ContractAddresses, createEthereumChain } from '@aztec/ethereum';
Expand Down Expand Up @@ -89,7 +87,6 @@ describe('L1Publisher integration', () => {
let outbox: GetContractReturnType<typeof OutboxAbi, PublicClient<HttpTransport, Chain>>;

let publisher: L1Publisher;
let l2Proof: Proof;

let builder: TxProver;
let builderDb: MerkleTrees;
Expand Down Expand Up @@ -147,7 +144,6 @@ describe('L1Publisher integration', () => {
const worldStateSynchronizer = new ServerWorldStateSynchronizer(tmpStore, builderDb, blockSource, worldStateConfig);
await worldStateSynchronizer.start();
builder = await TxProver.new(config, worldStateSynchronizer, new NoopTelemetryClient());
l2Proof = makeEmptyProof();

publisher = getL1Publisher({
rpcUrl: config.rpcUrl,
Expand Down Expand Up @@ -411,7 +407,7 @@ describe('L1Publisher integration', () => {

writeJson(`mixed_block_${i}`, block, l1ToL2Content, recipientAddress, deployerAccount.address);

await publisher.processL2Block(block, [], l2Proof);
await publisher.processL2Block(block);

const logs = await publicClient.getLogs({
address: rollupAddress,
Expand All @@ -431,12 +427,7 @@ describe('L1Publisher integration', () => {
const expectedData = encodeFunctionData({
abi: RollupAbi,
functionName: 'process',
args: [
`0x${block.header.toBuffer().toString('hex')}`,
`0x${block.archive.root.toBuffer().toString('hex')}`,
`0x`, // empty aggregation object
`0x${l2Proof.withoutPublicInputs().toString('hex')}`,
],
args: [`0x${block.header.toBuffer().toString('hex')}`, `0x${block.archive.root.toBuffer().toString('hex')}`],
});
expect(ethTx.input).toEqual(expectedData);

Expand Down Expand Up @@ -501,7 +492,7 @@ describe('L1Publisher integration', () => {

writeJson(`empty_block_${i}`, block, [], AztecAddress.ZERO, deployerAccount.address);

await publisher.processL2Block(block, [], l2Proof);
await publisher.processL2Block(block);

const logs = await publicClient.getLogs({
address: rollupAddress,
Expand All @@ -521,12 +512,7 @@ describe('L1Publisher integration', () => {
const expectedData = encodeFunctionData({
abi: RollupAbi,
functionName: 'process',
args: [
`0x${block.header.toBuffer().toString('hex')}`,
`0x${block.archive.root.toBuffer().toString('hex')}`,
`0x`, // empty aggregation object
`0x${l2Proof.withoutPublicInputs().toString('hex')}`,
],
args: [`0x${block.header.toBuffer().toString('hex')}`, `0x${block.archive.root.toBuffer().toString('hex')}`],
});
expect(ethTx.input).toEqual(expectedData);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ describe('proof_verification', () => {
`0x${proof.withoutPublicInputs().toString('hex')}`,
] as const;

await expect(rollupContract.write.process(args)).resolves.toBeDefined();
await expect(rollupContract.write.submitProof(args)).resolves.toBeDefined();
});
});
});
9 changes: 2 additions & 7 deletions yarn-project/noir-protocol-circuits-types/package.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,5 @@
"build": "yarn clean && yarn generate && tsc -b",
"clean": "rm -rf ./dest .tsbuildinfo src/types artifacts"
},
"files": [
"dest",
"src",
"artifacts",
"!*.test.*"
]
}
"files": ["dest", "src", "artifacts", "!*.test.*"]
}
9 changes: 2 additions & 7 deletions yarn-project/protocol-contracts/package.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,5 @@
"build:ts": "tsc -b",
"clean": "rm -rf ./dest .tsbuildinfo ./artifacts"
},
"files": [
"dest",
"src",
"artifacts",
"!*.test.*"
]
}
"files": ["dest", "src", "artifacts", "!*.test.*"]
}
4 changes: 2 additions & 2 deletions yarn-project/scripts/src/benchmarks/aggregate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
type CircuitProvingStats,
type CircuitSimulationStats,
type CircuitWitnessGenerationStats,
type L1PublishStats,
type L1PublishBlockStats,
type L2BlockBuiltStats,
type L2BlockHandledStats,
type MetricName,
Expand Down Expand Up @@ -87,7 +87,7 @@ function processAcirProofGenerated(entry: ProofConstructed, results: BenchmarkCo
}

/** Processes an entry with event name 'rollup-published-to-l1' and updates results */
function processRollupPublished(entry: L1PublishStats, results: BenchmarkCollectedResults) {
function processRollupPublished(entry: L1PublishBlockStats, results: BenchmarkCollectedResults) {
const bucket = entry.txCount;
if (!BENCHMARK_BLOCK_SIZES.includes(bucket)) {
return;
Expand Down
Loading
Loading