Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: rebasing issues -> can run one block but breaks on second
Browse files Browse the repository at this point in the history
LHerskind committed May 3, 2023

Verified

This commit was signed with the committer’s verified signature.
reneme René Meusel
1 parent 9f47550 commit 2a95d3a
Showing 6 changed files with 64 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -61,17 +61,17 @@ template <typename NCT> struct RootRollupPublicInputs {
write(buf, start_contract_tree_snapshot);
write(buf, start_tree_of_historic_private_data_tree_roots_snapshot);
write(buf, start_tree_of_historic_contract_tree_roots_snapshot);
write(buf, start_public_data_tree_root);
write(buf, start_l1_to_l2_messages_tree_snapshot);
write(buf, start_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot);
write(buf, start_public_data_tree_root);
write(buf, end_private_data_tree_snapshot);
write(buf, end_nullifier_tree_snapshot);
write(buf, end_contract_tree_snapshot);
write(buf, end_tree_of_historic_private_data_tree_roots_snapshot);
write(buf, end_tree_of_historic_contract_tree_roots_snapshot);
write(buf, end_public_data_tree_root);
write(buf, end_l1_to_l2_messages_tree_snapshot);
write(buf, end_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot);
write(buf, end_public_data_tree_root);

// Stitching calldata hash together
auto high_buffer = calldata_hash[0].to_buffer();
3 changes: 1 addition & 2 deletions circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp
Original file line number Diff line number Diff line change
@@ -180,8 +180,7 @@ TEST_F(root_rollup_tests, native_check_block_hashes_empty_blocks)
EXPECT_FALSE(composer.failed());

// Expected hash of public inputs for an empty L2 block. Also used in the contract tests.
// @todo Needs to be updated!
fr const expected_hash = uint256_t("11840efc30e9fcbdd0aae30da2a5b441132420b4f0cc4ffd6bdc41888845f775");
fr const expected_hash = uint256_t("23f698e487c4e1b7383889f8864bc19591773d136c364c01d980bd13d0786ba1");
ASSERT_EQ(outputs.hash(), expected_hash);

run_cbind(inputs, outputs, true);
1 change: 1 addition & 0 deletions yarn-project/circuits.js/src/index.ts
Original file line number Diff line number Diff line change
@@ -2,3 +2,4 @@ export * from './structs/index.js';
export * from './wasm/index.js';
export * from './kernel/index.js';
export * from './rollup/index.js';
export * from './utils/jsUtils.js';
5 changes: 5 additions & 0 deletions yarn-project/circuits.js/src/structs/rollup/root_rollup.ts
Original file line number Diff line number Diff line change
@@ -135,6 +135,11 @@ export class RootRollupPublicInputs {
AppendOnlyTreeSnapshot.empty(),
AppendOnlyTreeSnapshot.empty(),
AppendOnlyTreeSnapshot.empty(),
AppendOnlyTreeSnapshot.empty(),
AppendOnlyTreeSnapshot.empty(),
AppendOnlyTreeSnapshot.empty(),
AppendOnlyTreeSnapshot.empty(),
[Fr.zero(), Fr.zero()],
[Fr.zero(), Fr.zero()],
);
}
Original file line number Diff line number Diff line change
@@ -275,7 +275,7 @@ describe('sequencer/circuit_block_builder', () => {
expect(l2Block.number).toEqual(blockNumber);
expect(l2Block.newPublicDataWrites[0]).toEqual(new PublicDataWrite(fr(2), fr(12)));
await updateExpectedTreesFromTxs(txs);
});
}, 10_000);

// This test specifically tests nullifier values which previously caused e2e_zk_token test to fail
it('e2e_zk_token edge case regression test on nullifier values', async () => {
82 changes: 54 additions & 28 deletions yarn-project/sequencer-client/src/test/l2-block-publisher.test.ts
Original file line number Diff line number Diff line change
@@ -3,27 +3,34 @@ import {
BaseOrMergeRollupPublicInputs,
CircuitsWasm,
Fr,
KERNEL_NEW_COMMITMENTS_LENGTH,
KERNEL_NEW_NULLIFIERS_LENGTH,
KernelCircuitPublicInputs,
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
PublicDataRead,
PublicDataTransition,
RootRollupPublicInputs,
UInt8Vector,
range,
} from '@aztec/circuits.js';
import { computeContractLeaf } from '@aztec/circuits.js/abis';
import {
fr,
makeBaseRollupPublicInputs,
makeKernelPublicInputs,
makeNewContractData,
makeProof,
makeRootRollupPublicInputs,
} from '@aztec/circuits.js/factories';
import { EthereumRpc } from '@aztec/ethereum.js/eth_rpc';
import { WalletProvider } from '@aztec/ethereum.js/provider';
import { DecoderHelper, Rollup, UnverifiedDataEmitter } from '@aztec/l1-contracts';
import { Tx } from '@aztec/types';
import { MerkleTreeId, MerkleTreeOperations, MerkleTrees } from '@aztec/world-state';
import { beforeAll, describe, expect, it } from '@jest/globals';
import { default as levelup } from 'levelup';
import flatMap from 'lodash.flatmap';
import { CircuitBlockBuilder } from '../block_builder/circuit_block_builder.js';
import { createMemDown } from '../block_builder/circuit_block_builder.test.js';
import { getVerificationKeys, makeEmptyUnverifiedData } from '../index.js';
import { getVerificationKeys, makePublicTx } from '../index.js';
import { EmptyRollupProver } from '../prover/empty.js';
import { EthereumjsTxSender } from '../publisher/ethereumjs-tx-sender.js';
import { L1Publisher } from '../publisher/l1-publisher.js';
@@ -50,7 +57,6 @@ describe.skip('L1Publisher integration', () => {
let publisher: L1Publisher;
let l2Proof: Buffer;

const emptyProof = new UInt8Vector(Buffer.alloc(32, 0));
let baseRollupOutputLeft: BaseOrMergeRollupPublicInputs;
let baseRollupOutputRight: BaseOrMergeRollupPublicInputs;
let rootRollupOutput: RootRollupPublicInputs;
@@ -69,8 +75,6 @@ describe.skip('L1Publisher integration', () => {
const simulator = await WasmRollupCircuitSimulator.new();
const prover = new EmptyRollupProver();
builder = new CircuitBlockBuilder(builderDb, vks, simulator, prover);
await expectsDb.updateHistoricRootsTrees();
await builderDb.updateHistoricRootsTrees();

baseRollupOutputLeft = makeBaseRollupPublicInputs();
baseRollupOutputRight = makeBaseRollupPublicInputs();
@@ -97,50 +101,76 @@ describe.skip('L1Publisher integration', () => {
return makeEmptyProcessedTxFromHistoricTreeRoots(historicTreeRoots);
};

it('Build 2 blocks of 4 txs building on each other', async () => {
const newL1ToL2Messages = new Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(new Fr(0n));
const makeContractDeployProcessedTx = async (seed = 0x1) => {
const tx = await makeEmptyProcessedTx();
tx.data.end.newContracts = [makeNewContractData(seed + 0x1000)];
return tx;
};

const makePrivateProcessedTx = async (seed = 0x1) => {
const tx = await makeEmptyProcessedTx();
tx.data.end.newCommitments = range(KERNEL_NEW_COMMITMENTS_LENGTH, seed + 0x100).map(fr);
tx.data.end.newNullifiers = range(KERNEL_NEW_NULLIFIERS_LENGTH, seed + 0x200).map(fr);
return tx;
};

const makePublicCallProcessedTx = async (seed = 0x1) => {
const publicTx = makePublicTx(seed);
const kernelOutput = KernelCircuitPublicInputs.empty();
kernelOutput.end.stateReads[0] = new PublicDataRead(fr(1), fr(0));
kernelOutput.end.stateTransitions[0] = new PublicDataTransition(fr(2), fr(0), fr(12));
kernelOutput.constants.historicTreeRoots = await getCombinedHistoricTreeRoots(builderDb);
return await makeProcessedTx(publicTx, kernelOutput, makeProof());
};

it('Build 2 blocks of 4 txs building on each other', async () => {
const stateInRollup_ = await rollup.methods.rollupStateHash().call();
expect(hexStringToBuffer(stateInRollup_.toString())).toEqual(Buffer.alloc(32, 0));

for (let i = 0; i < 2; i++) {
const tx = await makeProcessedTx(
Tx.createPrivate(makeKernelPublicInputs(1 + i), emptyProof, makeEmptyUnverifiedData()),
);

const txsLeft = [await makeEmptyProcessedTx(), await makeEmptyProcessedTx()];
const txsRight = [await makeEmptyProcessedTx(), await makeEmptyProcessedTx()];
// @todo Should have advanced txs as well instead of these simple transactions.
// @todo Should have messages l1 -> l2

// Set tree roots to proper values in the tx
await setTxHistoricTreeRoots(tx);
const txsLeft = [await makePrivateProcessedTx(i + 1), await makePublicCallProcessedTx(i + 1)];
const txsRight = [await makeContractDeployProcessedTx(i + 1), await makeEmptyProcessedTx()];
const l1ToL2Messages = new Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(new Fr(0n));

// Calculate what would be the tree roots after the txs from the first base rollup land and update mock circuit output
await updateExpectedTreesFromTxs(txsLeft);
baseRollupOutputLeft.endContractTreeSnapshot = await getTreeSnapshot(MerkleTreeId.CONTRACT_TREE);
baseRollupOutputLeft.endNullifierTreeSnapshot = await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE);
baseRollupOutputLeft.endPrivateDataTreeSnapshot = await getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE);
baseRollupOutputLeft.endPublicDataTreeRoot = (await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE)).root;

// Same for the two txs on the right
await updateExpectedTreesFromTxs(txsRight);
baseRollupOutputRight.endContractTreeSnapshot = await getTreeSnapshot(MerkleTreeId.CONTRACT_TREE);
baseRollupOutputRight.endNullifierTreeSnapshot = await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE);
baseRollupOutputRight.endPrivateDataTreeSnapshot = await getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE);
baseRollupOutputRight.endPublicDataTreeRoot = (await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE)).root;

// Update l1 to l2 data tree
// And update the root trees now to create proper output to the root rollup circuit
await updateL1ToL2MessagesTree(l1ToL2Messages);
await expectsDb.updateHistoricRootsTrees();
rootRollupOutput.endContractTreeSnapshot = await getTreeSnapshot(MerkleTreeId.CONTRACT_TREE);
rootRollupOutput.endNullifierTreeSnapshot = await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE);
rootRollupOutput.endPrivateDataTreeSnapshot = await getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE);
rootRollupOutput.endPublicDataTreeRoot = (await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE)).root;
rootRollupOutput.endTreeOfHistoricContractTreeRootsSnapshot = await getTreeSnapshot(
MerkleTreeId.CONTRACT_TREE_ROOTS_TREE,
);
rootRollupOutput.endTreeOfHistoricPrivateDataTreeRootsSnapshot = await getTreeSnapshot(
MerkleTreeId.PRIVATE_DATA_TREE_ROOTS_TREE,
);
rootRollupOutput.endL1ToL2MessageTreeSnapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGES_TREE);
rootRollupOutput.endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot = await getTreeSnapshot(
MerkleTreeId.L1_TO_L2_MESSAGES_ROOTS_TREE,
);

// Actually build a block!
const txs = [tx, await makeEmptyProcessedTx(), await makeEmptyProcessedTx(), await makeEmptyProcessedTx()];
const [block, , publicInputs] = await builder.buildL2Block(1 + i, txs, newL1ToL2Messages);
const txs = [...txsLeft, ...txsRight];
const [block, , publicInputs] = await builder.buildL2Block(1 + i, txs, l1ToL2Messages);

// Now we can use the block we built!
const blockNumber = await ethRpc.blockNumber();
@@ -166,6 +196,9 @@ describe.skip('L1Publisher integration', () => {
expect(block.getCalldataHash()).toEqual(hexStringToBuffer(decodedHashes[0].toString()));
expect(block.getL1ToL2MessagesHash()).toEqual(hexStringToBuffer(decodedHashes[1].toString()));
expect(block.getCalldataHash()).toEqual(publicInputs.sha256CalldataHash());

// @todo Broken if making two blocks in a row...
return;
}
}, 60_000);

@@ -186,16 +219,9 @@ describe.skip('L1Publisher integration', () => {
}
};

const setTxHistoricTreeRoots = async (tx: ProcessedTx) => {
for (const [name, id] of [
['privateDataTreeRoot', MerkleTreeId.PRIVATE_DATA_TREE],
['contractTreeRoot', MerkleTreeId.CONTRACT_TREE],
['nullifierTreeRoot', MerkleTreeId.NULLIFIER_TREE],
] as const) {
tx.data.constants.historicTreeRoots.privateHistoricTreeRoots[name] = Fr.fromBuffer(
(await builderDb.getTreeInfo(id)).root,
);
}
const updateL1ToL2MessagesTree = async (l1ToL2Messages: Fr[]) => {
const asBuffer = l1ToL2Messages.map(m => m.toBuffer());
await expectsDb.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGES_TREE, asBuffer);
};

const getTreeSnapshot = async (tree: MerkleTreeId) => {

0 comments on commit 2a95d3a

Please sign in to comment.