Skip to content

Commit

Permalink
remove l2BlockNum from inbox leaf
Browse files Browse the repository at this point in the history
  • Loading branch information
rahul-kothari committed Oct 10, 2024
1 parent 7d777a6 commit 8c7f739
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 104 deletions.
34 changes: 19 additions & 15 deletions yarn-project/archiver/src/archiver/archiver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,18 +117,18 @@ describe('Archiver', () => {

mockGetLogs({
messageSent: [
makeMessageSentEventWithIndexInSubtree(98n, 1n, 0n),
makeMessageSentEventWithIndexInSubtree(99n, 1n, 1n),
makeMessageSentEventWithIndexInL2BlockSubtree(98n, 1n, 0n),
makeMessageSentEventWithIndexInL2BlockSubtree(99n, 1n, 1n),
],
L2BlockProposed: [makeL2BlockProposedEvent(101n, 1n, blocks[0].archive.root.toString())],
});

mockGetLogs({
messageSent: [
makeMessageSentEventWithIndexInSubtree(2504n, 2n, 0n),
makeMessageSentEventWithIndexInSubtree(2505n, 2n, 1n),
makeMessageSentEventWithIndexInSubtree(2505n, 2n, 2n),
makeMessageSentEventWithIndexInSubtree(2506n, 3n, 1n),
makeMessageSentEventWithIndexInL2BlockSubtree(2504n, 2n, 0n),
makeMessageSentEventWithIndexInL2BlockSubtree(2505n, 2n, 1n),
makeMessageSentEventWithIndexInL2BlockSubtree(2505n, 2n, 2n),
makeMessageSentEventWithIndexInL2BlockSubtree(2506n, 3n, 1n),
],
L2BlockProposed: [
makeL2BlockProposedEvent(2510n, 2n, blocks[1].archive.root.toString()),
Expand Down Expand Up @@ -227,8 +227,8 @@ describe('Archiver', () => {

mockGetLogs({
messageSent: [
makeMessageSentEventWithIndexInSubtree(66n, 1n, 0n),
makeMessageSentEventWithIndexInSubtree(68n, 1n, 1n),
makeMessageSentEventWithIndexInL2BlockSubtree(66n, 1n, 0n),
makeMessageSentEventWithIndexInL2BlockSubtree(68n, 1n, 1n),
],
L2BlockProposed: [
makeL2BlockProposedEvent(70n, 1n, blocks[0].archive.root.toString()),
Expand Down Expand Up @@ -270,8 +270,8 @@ describe('Archiver', () => {

mockGetLogs({
messageSent: [
makeMessageSentEventWithIndexInSubtree(66n, 1n, 0n),
makeMessageSentEventWithIndexInSubtree(68n, 1n, 1n),
makeMessageSentEventWithIndexInL2BlockSubtree(66n, 1n, 0n),
makeMessageSentEventWithIndexInL2BlockSubtree(68n, 1n, 1n),
],
L2BlockProposed: [
makeL2BlockProposedEvent(70n, 1n, blocks[0].archive.root.toString()),
Expand Down Expand Up @@ -330,8 +330,8 @@ describe('Archiver', () => {

mockGetLogs({
messageSent: [
makeMessageSentEventWithIndexInSubtree(66n, 1n, 0n),
makeMessageSentEventWithIndexInSubtree(68n, 1n, 1n),
makeMessageSentEventWithIndexInL2BlockSubtree(66n, 1n, 0n),
makeMessageSentEventWithIndexInL2BlockSubtree(68n, 1n, 1n),
],
L2BlockProposed: [
makeL2BlockProposedEvent(70n, 1n, blocks[0].archive.root.toString()),
Expand Down Expand Up @@ -380,7 +380,7 @@ describe('Archiver', () => {

// logs should be created in order of how archiver syncs.
const mockGetLogs = (logs: {
messageSent?: ReturnType<typeof makeMessageSentEventWithIndexInSubtree>[];
messageSent?: ReturnType<typeof makeMessageSentEventWithIndexInL2BlockSubtree>[];
L2BlockProposed?: ReturnType<typeof makeL2BlockProposedEvent>[];
}) => {
if (logs.messageSent) {
Expand Down Expand Up @@ -412,8 +412,12 @@ function makeL2BlockProposedEvent(l1BlockNum: bigint, l2BlockNum: bigint, archiv
* @param l2BlockNumber - The L2 block number of in which the message was included.
* @returns MessageSent event logs.
*/
function makeMessageSentEventWithIndexInSubtree(l1BlockNum: bigint, l2BlockNumber: bigint, indexInSubtree: bigint) {
const index = InboxLeaf.convertToIndexInWholeTree(indexInSubtree, l2BlockNumber);
function makeMessageSentEventWithIndexInL2BlockSubtree(
l1BlockNum: bigint,
l2BlockNumber: bigint,
indexInSubtree: bigint,
) {
const index = indexInSubtree + InboxLeaf.smallestIndexFromL2Block(l2BlockNumber);
return {
blockNumber: l1BlockNum,
args: {
Expand Down
25 changes: 9 additions & 16 deletions yarn-project/archiver/src/archiver/archiver_store_test_suite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,10 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
} satisfies ArchiverL1SynchPoint);
});

it.skip('returns the L1 block number that most recently added messages from inbox', async () => {
// unsure what to do if blockNum is 0 lol - unsure what this test actually does
it('returns the L1 block number that most recently added messages from inbox', async () => {
await store.addL1ToL2Messages({
lastProcessedL1BlockNumber: 1n,
retrievedData: [new InboxLeaf(0n, 0n, Fr.ZERO)],
retrievedData: [new InboxLeaf(1n, Fr.ZERO)],
});
await expect(store.getSynchPoint()).resolves.toEqual({
blocksSynchedTo: undefined,
Expand Down Expand Up @@ -227,8 +226,9 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
const l1ToL2MessageSubtreeSize = 2 ** L1_TO_L2_MSG_SUBTREE_HEIGHT;

const generateBlockMessages = (blockNumber: bigint, numMessages: number) =>
Array.from({ length: numMessages }, (_, i) =>
InboxLeaf.createInboxLeafUsingIndexInSubtree(blockNumber, BigInt(i), Fr.random()),
Array.from(
{ length: numMessages },
(_, i) => new InboxLeaf(InboxLeaf.smallestIndexFromL2Block(blockNumber) + BigInt(i), Fr.random()),
);

it('returns messages in correct order', async () => {
Expand All @@ -244,26 +244,19 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
it('throws if it is impossible to sequence messages correctly', async () => {
const msgs = generateBlockMessages(l2BlockNumber, l1ToL2MessageSubtreeSize - 1);
// We replace a message with index 4 with a message with index at the end of the tree
// --> with that there will be a gap and it will be impossible to sequence the messages
msgs[4] = new InboxLeaf(l2BlockNumber, BigInt(l1ToL2MessageSubtreeSize - 1), Fr.random());
// --> with that there will be a gap and it will be impossible to sequence the
// end of tree = start of next tree/block - 1
msgs[4] = new InboxLeaf(InboxLeaf.smallestIndexFromL2Block(l2BlockNumber + 1n) - 1n, Fr.random());

await store.addL1ToL2Messages({ lastProcessedL1BlockNumber: 100n, retrievedData: msgs });
await expect(async () => {
await store.getL1ToL2Messages(l2BlockNumber);
}).rejects.toThrow(`L1 to L2 message gap found in block ${l2BlockNumber}`);
});

it('throws if adding more messages than fits into a block', async () => {
const msgs = generateBlockMessages(l2BlockNumber, l1ToL2MessageSubtreeSize + 1);

await expect(async () => {
await store.addL1ToL2Messages({ lastProcessedL1BlockNumber: 100n, retrievedData: msgs });
}).rejects.toThrow(`Message index ${l1ToL2MessageSubtreeSize} out of subtree range`);
});

it('correctly handles duplicate messages', async () => {
const messageHash = Fr.random();
const msgs = [new InboxLeaf(1n, 0n, messageHash), new InboxLeaf(2n, 16n, messageHash)];
const msgs = [new InboxLeaf(0n, messageHash), new InboxLeaf(16n, messageHash)];

await store.addL1ToL2Messages({ lastProcessedL1BlockNumber: 100n, retrievedData: msgs });

Expand Down
4 changes: 2 additions & 2 deletions yarn-project/archiver/src/archiver/data_retrieval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,8 @@ export async function retrieveL1ToL2Messages(
}

for (const log of messageSentLogs) {
const { l2BlockNumber, index, hash } = log.args;
retrievedL1ToL2Messages.push(new InboxLeaf(l2BlockNumber!, index!, Fr.fromString(hash!)));
const { index, hash } = log.args;
retrievedL1ToL2Messages.push(new InboxLeaf(index!, Fr.fromString(hash!)));
}

// handles the case when there are no new messages:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type InboxLeaf } from '@aztec/circuit-types';
import { InboxLeaf } from '@aztec/circuit-types';
import { Fr, L1_TO_L2_MSG_SUBTREE_HEIGHT } from '@aztec/circuits.js';
import { createDebugLogger } from '@aztec/foundation/log';
import { type AztecKVStore, type AztecMap, type AztecSingleton } from '@aztec/kv-store';
Expand Down Expand Up @@ -56,18 +56,11 @@ export class MessageStore {
void this.#lastSynchedL1Block.set(messages.lastProcessedL1BlockNumber);

for (const message of messages.retrievedData) {
// inbox event emits index the whole tree. We need index in the L1 to L2 message subtree.
// reverse of what is done in inbox.sol
const indexInTheWholeTree = message.index;
const indexInSubtree = message.convertToIndexInSubtree();
if (indexInSubtree >= this.#l1ToL2MessagesSubtreeSize) {
throw new Error(`Message index ${indexInSubtree} out of subtree range`);
}
const key = `${message.blockNumber}-${indexInSubtree}`;
const key = `${message.index}`;
void this.#l1ToL2Messages.setIfNotExists(key, message.leaf.toBuffer());

const indices = this.#l1ToL2MessageIndices.get(message.leaf.toString()) ?? [];
indices.push(indexInTheWholeTree);
indices.push(message.index);
void this.#l1ToL2MessageIndices.set(message.leaf.toString(), indices);
}

Expand All @@ -93,9 +86,10 @@ export class MessageStore {
getL1ToL2Messages(blockNumber: bigint): Fr[] {
const messages: Fr[] = [];
let undefinedMessageFound = false;
for (let messageIndex = 0; messageIndex < this.#l1ToL2MessagesSubtreeSize; messageIndex++) {
const startIndex = Number(InboxLeaf.smallestIndexFromL2Block(blockNumber));
for (let i = startIndex; i < startIndex + this.#l1ToL2MessagesSubtreeSize; i++) {
// This is inefficient but probably fine for now.
const key = `${blockNumber}-${messageIndex}`;
const key = `${i}`;
const message = this.#l1ToL2Messages.get(key);
if (message) {
if (undefinedMessageFound) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { InboxLeaf } from '@aztec/circuit-types';
import { INITIAL_L2_BLOCK_NUM, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/circuits.js';
import { Fr } from '@aztec/foundation/fields';

import { L1ToL2MessageStore } from './l1_to_l2_message_store.js';
Expand All @@ -14,7 +15,7 @@ describe('l1_to_l2_message_store', () => {
it('adds a message and correctly returns its index', () => {
const blockNumber = 236n;
const msgs = Array.from({ length: 10 }, (_, i) => {
return InboxLeaf.createInboxLeafUsingIndexInSubtree(blockNumber, BigInt(i), Fr.random());
return new InboxLeaf(InboxLeaf.smallestIndexFromL2Block(blockNumber) + BigInt(i), Fr.random());
});
for (const m of msgs) {
store.addMessage(m);
Expand All @@ -24,15 +25,17 @@ describe('l1_to_l2_message_store', () => {
expect(retrievedMsgs.length).toEqual(10);

const msg = msgs[4];
const expectedIndexInWholeTree = store.getMessageIndex(msg.leaf, 0n)!;
expect(expectedIndexInWholeTree).toEqual(InboxLeaf.convertToIndexInWholeTree(4n, blockNumber));
const expectedIndex = store.getMessageIndex(msg.leaf, 0n)!;
expect(expectedIndex).toEqual(
(blockNumber - BigInt(INITIAL_L2_BLOCK_NUM)) * BigInt(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP) + 4n,
);
});

it('correctly handles duplicate messages', () => {
const messageHash = Fr.random();

store.addMessage(InboxLeaf.createInboxLeafUsingIndexInSubtree(1n, 0n, messageHash));
store.addMessage(InboxLeaf.createInboxLeafUsingIndexInSubtree(2n, 0n, messageHash));
store.addMessage(new InboxLeaf(0n, messageHash)); // l2 block 1
store.addMessage(new InboxLeaf(16n, messageHash)); // l2 block 2

const index1 = store.getMessageIndex(messageHash, 0n)!;
const index2 = store.getMessageIndex(messageHash, index1 + 1n);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { type Fr } from '@aztec/foundation/fields';
*/
export class L1ToL2MessageStore {
/**
* A map pointing from a key in a "blockNum-messageIndex" format to the corresponding L1 to L2 message hash.
* A map pointing from a key in a "messageIndex" format to the corresponding L1 to L2 message hash.
*/
protected store: Map<string, Fr> = new Map();

Expand All @@ -20,21 +20,17 @@ export class L1ToL2MessageStore {
}

addMessage(message: InboxLeaf) {
const indexInSubtree = message.convertToIndexInSubtree();
if (indexInSubtree >= this.#l1ToL2MessagesSubtreeSize) {
throw new Error(`Message index ${indexInSubtree} out of subtree range`);
}
const key = `${message.blockNumber}-${indexInSubtree}`;
this.store.set(key, message.leaf);
this.store.set(`${message.index}`, message.leaf);
}

getMessages(blockNumber: bigint): Fr[] {
const messages: Fr[] = [];
let undefinedMessageFound = false;
for (let messageIndex = 0; messageIndex < this.#l1ToL2MessagesSubtreeSize; messageIndex++) {
const startIndex = Number(InboxLeaf.smallestIndexFromL2Block(blockNumber));

for (let i = startIndex; i < startIndex + this.#l1ToL2MessagesSubtreeSize; i++) {
// This is inefficient but probably fine for now.
const key = `${blockNumber}-${messageIndex}`;
const message = this.store.get(key);
const message = this.store.get(`${i}`);
if (message) {
if (undefinedMessageFound) {
throw new Error(`L1 to L2 message gap found in block ${blockNumber}`);
Expand All @@ -58,9 +54,7 @@ export class L1ToL2MessageStore {
getMessageIndex(l1ToL2Message: Fr, startIndex: bigint): bigint | undefined {
for (const [key, message] of this.store.entries()) {
if (message.equals(l1ToL2Message)) {
const keyParts = key.split('-');
const [blockNumber, messageIndex] = [BigInt(keyParts[0]), BigInt(keyParts[1])];
const indexInTheWholeTree = InboxLeaf.convertToIndexInWholeTree(messageIndex, blockNumber);
const indexInTheWholeTree = BigInt(key);
if (indexInTheWholeTree < startIndex) {
continue;
}
Expand Down
20 changes: 0 additions & 20 deletions yarn-project/circuit-types/src/messaging/inbox_leaf.test.ts

This file was deleted.

25 changes: 4 additions & 21 deletions yarn-project/circuit-types/src/messaging/inbox_leaf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,24 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';

export class InboxLeaf {
constructor(
/** L2 block number in which the message will be included. */
public readonly blockNumber: bigint,
/** Index of the leaf in the whole tree. */
public readonly index: bigint,
/** Leaf in the subtree/message hash. */
public readonly leaf: Fr,
) {}

toBuffer(): Buffer {
return serializeToBuffer([this.blockNumber, this.index, this.leaf]);
return serializeToBuffer([this.index, this.leaf]);
}

fromBuffer(buffer: Buffer | BufferReader): InboxLeaf {
const reader = BufferReader.asReader(buffer);
const blockNumber = toBigIntBE(reader.readBytes(32));
const index = toBigIntBE(reader.readBytes(32));
const leaf = reader.readObject(Fr);
return new InboxLeaf(blockNumber, index, leaf);
return new InboxLeaf(index, leaf);
}

static createInboxLeafUsingIndexInSubtree(blockNumber: bigint, indexInSubtree: bigint, leaf: Fr): InboxLeaf {
return new InboxLeaf(blockNumber, this.convertToIndexInWholeTree(indexInSubtree, blockNumber), leaf);
}

convertToIndexInSubtree(): bigint {
if (this.blockNumber < BigInt(INITIAL_L2_BLOCK_NUM)) {
return 0n; //what tto actually do???? it fails this test
// https://github.com/AztecProtocol/aztec-packages/blob/aa106cc2dd49d88a7259e5ccdfa61a477c5258e1/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts#L118
// getSynchPoint test - returns the L1 block number that most recently added messages from inbox
}
return this.index - (this.blockNumber - BigInt(INITIAL_L2_BLOCK_NUM)) * BigInt(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
}

// the opposite of the previous function - takes index in a subtree and returns the index in the whole tree.
static convertToIndexInWholeTree(i: bigint, l2Block: bigint): bigint {
return i + (l2Block - BigInt(INITIAL_L2_BLOCK_NUM)) * BigInt(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
static smallestIndexFromL2Block(l2block: bigint): bigint {
return (l2block - BigInt(INITIAL_L2_BLOCK_NUM)) * BigInt(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
}
}

0 comments on commit 8c7f739

Please sign in to comment.