Skip to content

Commit

Permalink
fix: Align block structs w/ yp #3868 (#4541)
Browse files Browse the repository at this point in the history
Resolves #3868 and #4635
  • Loading branch information
sklppy88 authored Feb 20, 2024
1 parent 20e7605 commit 081da3c
Show file tree
Hide file tree
Showing 34 changed files with 641 additions and 1,727 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ cmake-build-debug
.netlify

.graphite*
.DS_Store
22 changes: 11 additions & 11 deletions yarn-project/archiver/src/archiver/archiver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@ describe('Archiver', () => {
const l1ToL2MessageAddedEvents = [
makeL1ToL2MessageAddedEvents(
100n,
blocks[0].newL1ToL2Messages.map(key => key.toString()),
blocks[0].body.l1ToL2Messages.map(key => key.toString()),
),
makeL1ToL2MessageAddedEvents(
100n,
blocks[1].newL1ToL2Messages.map(key => key.toString()),
blocks[1].body.l1ToL2Messages.map(key => key.toString()),
),
makeL1ToL2MessageAddedEvents(
2501n,
blocks[2].newL1ToL2Messages.map(key => key.toString()),
blocks[2].body.l1ToL2Messages.map(key => key.toString()),
),
makeL1ToL2MessageAddedEvents(2502n, [
messageToCancel1,
Expand Down Expand Up @@ -162,11 +162,11 @@ describe('Archiver', () => {
const l1ToL2MessageAddedEvents = [
makeL1ToL2MessageAddedEvents(
100n,
blocks[0].newL1ToL2Messages.map(key => key.toString()),
blocks[0].body.l1ToL2Messages.map(key => key.toString()),
),
makeL1ToL2MessageAddedEvents(
101n,
blocks[1].newL1ToL2Messages.map(key => key.toString()),
blocks[1].body.l1ToL2Messages.map(key => key.toString()),
),
makeL1ToL2MessageAddedEvents(102n, additionalL1ToL2MessagesBlock102),
makeL1ToL2MessageAddedEvents(103n, additionalL1ToL2MessagesBlock103),
Expand Down Expand Up @@ -223,7 +223,7 @@ describe('Archiver', () => {
expect(latestBlockNum).toEqual(0);

const block = L2Block.random(1, 4, 1, 2, 4, 6);
block.newL1ToL2Messages = times(2, Fr.random);
block.body.l1ToL2Messages = times(2, Fr.random);
const rollupTx = makeRollupTx(block);

publicClient.getBlockNumber.mockResolvedValueOnce(2500n);
Expand All @@ -232,7 +232,7 @@ describe('Archiver', () => {
.mockResolvedValueOnce(
makeL1ToL2MessageAddedEvents(
100n,
block.newL1ToL2Messages.map(x => x.toString()),
block.body.l1ToL2Messages.map(x => x.toString()),
),
)
.mockResolvedValueOnce([])
Expand All @@ -250,11 +250,11 @@ describe('Archiver', () => {
latestBlockNum = await archiver.getBlockNumber();
expect(latestBlockNum).toEqual(1);

const expectedL1Messages = block.newL1ToL2Messages
const expectedL1Messages = block.body.l1ToL2Messages
.concat(times(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP - NUM_RECEIVED_L1_MESSAGES, () => Fr.ZERO))
.map(x => x.value);
const receivedBlock = await archiver.getBlock(1);
expect(receivedBlock?.newL1ToL2Messages.map(x => x.value)).toEqual(expectedL1Messages);
expect(receivedBlock?.body.l1ToL2Messages.map(x => x.value)).toEqual(expectedL1Messages);

await archiver.stop();
}, 10_000);
Expand Down Expand Up @@ -289,7 +289,7 @@ function makeContractDeploymentEvent(l1BlockNum: bigint, l2Block: L2Block) {
l2BlockNum: BigInt(l2Block.number),
aztecAddress: extendedContractData.contractData.contractAddress.toString(),
portalAddress: extendedContractData.contractData.portalContractAddress.toString(),
l2BlockHash: `0x${l2Block.getCalldataHash().toString('hex')}`,
l2BlockHash: `0x${l2Block.body.getCalldataHash().toString('hex')}`,
contractClassId: extendedContractData.contractClassId.toString(),
saltedInitializationHash: extendedContractData.saltedInitializationHash.toString(),
publicKeyHash: extendedContractData.publicKeyHash.toString(),
Expand Down Expand Up @@ -351,7 +351,7 @@ function makeL1ToL2MessageCancelledEvents(l1BlockNum: bigint, entryKeys: string[
function makeRollupTx(l2Block: L2Block) {
const header = toHex(l2Block.header.toBuffer());
const archive = toHex(l2Block.archive.root.toBuffer());
const body = toHex(l2Block.bodyToBuffer());
const body = toHex(l2Block.body.toBuffer());
const proof = `0x`;
const input = encodeFunctionData({
abi: RollupAbi,
Expand Down
30 changes: 19 additions & 11 deletions yarn-project/archiver/src/archiver/archiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ import {
ContractInstanceWithAddress,
} from '@aztec/types/contracts';

import omit from 'lodash.omit';
import { Chain, HttpTransport, PublicClient, createPublicClient, http } from 'viem';

import { ArchiverDataStore } from './archiver_store.js';
Expand Down Expand Up @@ -267,31 +266,35 @@ export class Archiver implements ArchiveSource {
}

// create the block number -> block hash mapping to ensure we retrieve the appropriate events
const blockHashMapping: { [key: number]: Buffer | undefined } = {};
const blockNumberToBodyHash: { [key: number]: Buffer | undefined } = {};
retrievedBlocks.retrievedData.forEach((block: L2Block) => {
blockHashMapping[block.number] = block.getCalldataHash();
blockNumberToBodyHash[block.number] = block.body.getCalldataHash();
});
const retrievedContracts = await retrieveNewContractData(
this.publicClient,
this.contractDeploymentEmitterAddress,
blockUntilSynced,
lastL1Blocks.addedBlock + 1n,
currentL1BlockNumber,
blockHashMapping,
blockNumberToBodyHash,
);

this.log(`Retrieved ${retrievedBlocks.retrievedData.length} block(s) from chain`);

await Promise.all(
retrievedBlocks.retrievedData.map(block =>
this.store.addLogs(block.newEncryptedLogs, block.newUnencryptedLogs, block.number),
),
retrievedBlocks.retrievedData.map(block => {
const encryptedLogs = block.body.encryptedLogs;
const unencryptedLogs = block.body.unencryptedLogs;

return this.store.addLogs(encryptedLogs, unencryptedLogs, block.number);
}),
);

// Unroll all logs emitted during the retrieved blocks and extract any contract classes and instances from them
await Promise.all(
retrievedBlocks.retrievedData.map(async block => {
const blockLogs = (block.newUnencryptedLogs?.txLogs ?? [])
const blockLogs = block.body.txEffects
.flatMap(txEffect => (txEffect ? [txEffect.unencryptedLogs] : []))
.flatMap(txLog => txLog.unrollLogs())
.map(log => UnencryptedL2Log.fromBuffer(log));
await this.storeRegisteredContractClasses(blockLogs, block.number);
Expand All @@ -315,16 +318,21 @@ export class Archiver implements ArchiveSource {
// from each l2block fetch all messageKeys in a flattened array:
this.log(`Confirming l1 to l2 messages in store`);
for (const block of retrievedBlocks.retrievedData) {
await this.store.confirmL1ToL2Messages(block.newL1ToL2Messages);
await this.store.confirmL1ToL2Messages(block.body.l1ToL2Messages);
}

// store retrieved L2 blocks after removing new logs information.
// remove logs to serve "lightweight" block information. Logs can be fetched separately if needed.
await this.store.addBlocks(
retrievedBlocks.retrievedData.map(block => {
// Ensure we pad the L1 to L2 message array to the full size before storing.
block.newL1ToL2Messages = padArrayEnd(block.newL1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
return L2Block.fromFields(omit(block, ['newEncryptedLogs', 'newUnencryptedLogs']), block.getL1BlockNumber());
block.body.l1ToL2Messages = padArrayEnd(
block.body.l1ToL2Messages,
Fr.ZERO,
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
);

return block;
}),
);
}
Expand Down
39 changes: 21 additions & 18 deletions yarn-project/archiver/src/archiver/archiver_store_test_suite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
describe('addLogs', () => {
it('adds encrypted & unencrypted logs', async () => {
await expect(
store.addLogs(blocks[0].newEncryptedLogs, blocks[0].newUnencryptedLogs, blocks[0].number),
store.addLogs(blocks[0].body.encryptedLogs, blocks[0].body.unencryptedLogs, blocks[0].number),
).resolves.toEqual(true);
});
});
Expand All @@ -138,13 +138,13 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
])('getLogs (%s)', (_, logType) => {
beforeEach(async () => {
await Promise.all(
blocks.map(block => store.addLogs(block.newEncryptedLogs, block.newUnencryptedLogs, block.number)),
blocks.map(block => store.addLogs(block.body.encryptedLogs, block.body.unencryptedLogs, block.number)),
);
});

it.each(blockTests)('retrieves previously stored logs', async (from, limit, getExpectedBlocks) => {
const expectedLogs = getExpectedBlocks().map(block =>
logType === LogType.ENCRYPTED ? block.newEncryptedLogs : block.newUnencryptedLogs,
logType === LogType.ENCRYPTED ? block.body.encryptedLogs : block.body.unencryptedLogs,
);
const actualLogs = await store.getLogs(from, limit, logType);
expect(actualLogs).toEqual(expectedLogs);
Expand All @@ -154,7 +154,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
describe('getL2Tx', () => {
beforeEach(async () => {
await Promise.all(
blocks.map(block => store.addLogs(block.newEncryptedLogs, block.newUnencryptedLogs, block.number)),
blocks.map(block => store.addLogs(block.body.encryptedLogs, block.body.unencryptedLogs, block.number)),
);
await store.addBlocks(blocks);
});
Expand Down Expand Up @@ -366,9 +366,11 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
});

it('returns previously stored contract data', async () => {
await expect(store.getContractData(block.newContractData[0].contractAddress)).resolves.toEqual(
block.newContractData[0],
await expect(store.getContractData(block.body.txEffects[0].contractData[0].contractAddress)).resolves.toEqual(
block.body.txEffects[0].contractData[0],
);

expect(block.body.txEffects[0].contractData[1]).toBe(undefined);
});

it('returns undefined if contract data is not found', async () => {
Expand All @@ -384,7 +386,9 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
});

it('returns the contract data for a known block', async () => {
await expect(store.getContractDataInBlock(block.number)).resolves.toEqual(block.newContractData);
await expect(store.getContractDataInBlock(block.number)).resolves.toEqual(
block.body.txEffects.flatMap(txEffect => txEffect.contractData),
);
});

it('returns an empty array if contract data is not found', async () => {
Expand All @@ -409,10 +413,11 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
const block = L2Block.random(1);
await store.addBlocks([block]);

const firstContract = ExtendedContractData.random(block.newContractData[0]);
// Assuming one contract per tx, and the first two txs
const firstContract = ExtendedContractData.random(block.body.txEffects[0].contractData[0]);
await store.addExtendedContractData([firstContract], block.number);

const secondContract = ExtendedContractData.random(block.newContractData[1]);
const secondContract = ExtendedContractData.random(block.body.txEffects[1].contractData[0]);
await store.addExtendedContractData([secondContract], block.number);

await expect(store.getExtendedContractDataInBlock(block.number)).resolves.toEqual([
Expand All @@ -427,7 +432,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
let extendedContractData: ExtendedContractData;
beforeEach(async () => {
block = L2Block.random(1);
extendedContractData = ExtendedContractData.random(block.newContractData[0]);
extendedContractData = ExtendedContractData.random(block.body.txEffects[0].contractData[0]);
await store.addBlocks([block]);
await store.addExtendedContractData([extendedContractData], block.number);
});
Expand All @@ -448,7 +453,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
let extendedContractData: ExtendedContractData;
beforeEach(async () => {
block = L2Block.random(1);
extendedContractData = ExtendedContractData.random(block.newContractData[0]);
extendedContractData = ExtendedContractData.random(block.body.txEffects[0].contractData[0]);
await store.addBlocks([block]);
await store.addExtendedContractData([extendedContractData], block.number);
});
Expand Down Expand Up @@ -478,7 +483,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch

await store.addBlocks(blocks);
await Promise.all(
blocks.map(block => store.addLogs(block.newEncryptedLogs, block.newUnencryptedLogs, block.number)),
blocks.map(block => store.addLogs(block.body.encryptedLogs, block.body.unencryptedLogs, block.number)),
);
});

Expand Down Expand Up @@ -530,9 +535,8 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
const targetFunctionLogIndex = Math.floor(Math.random() * numPublicFunctionCalls);
const targetLogIndex = Math.floor(Math.random() * numUnencryptedLogs);
const targetContractAddress = UnencryptedL2Log.fromBuffer(
blocks[targetBlockIndex].newUnencryptedLogs!.txLogs[targetTxIndex].functionLogs[targetFunctionLogIndex].logs[
targetLogIndex
],
blocks[targetBlockIndex].body.txEffects[targetTxIndex].unencryptedLogs.functionLogs[targetFunctionLogIndex]
.logs[targetLogIndex],
).contractAddress;

const response = await store.getUnencryptedLogs({ contractAddress: targetContractAddress });
Expand All @@ -551,9 +555,8 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
const targetFunctionLogIndex = Math.floor(Math.random() * numPublicFunctionCalls);
const targetLogIndex = Math.floor(Math.random() * numUnencryptedLogs);
const targetSelector = UnencryptedL2Log.fromBuffer(
blocks[targetBlockIndex].newUnencryptedLogs!.txLogs[targetTxIndex].functionLogs[targetFunctionLogIndex].logs[
targetLogIndex
],
blocks[targetBlockIndex].body.txEffects[targetTxIndex].unencryptedLogs.functionLogs[targetFunctionLogIndex]
.logs[targetLogIndex],
).selector;

const response = await store.getUnencryptedLogs({ selector: targetSelector });
Expand Down
6 changes: 3 additions & 3 deletions yarn-project/archiver/src/archiver/data_retrieval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export async function retrieveBlocks(
* @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 blockHashMapping - A mapping from block number to relevant block hash.
* @param blockNumberToBodyHash - A mapping from block number to relevant body hash.
* @returns An array of ExtendedContractData and their equivalent L2 Block number along with the next eth block to search from..
*/
export async function retrieveNewContractData(
Expand All @@ -86,7 +86,7 @@ export async function retrieveNewContractData(
blockUntilSynced: boolean,
searchStartBlock: bigint,
searchEndBlock: bigint,
blockHashMapping: { [key: number]: Buffer | undefined },
blockNumberToBodyHash: { [key: number]: Buffer | undefined },
): Promise<DataRetrieval<[ExtendedContractData[], number]>> {
let retrievedNewContracts: [ExtendedContractData[], number][] = [];
do {
Expand All @@ -102,7 +102,7 @@ export async function retrieveNewContractData(
if (contractDataLogs.length === 0) {
break;
}
const newContracts = processContractDeploymentLogs(blockHashMapping, contractDataLogs);
const newContracts = processContractDeploymentLogs(blockNumberToBodyHash, contractDataLogs);
retrievedNewContracts = retrievedNewContracts.concat(newContracts);
searchStartBlock = (contractDataLogs.findLast(cd => !!cd)?.blockNumber || searchStartBlock) + 1n;
} while (blockUntilSynced && searchStartBlock <= searchEndBlock);
Expand Down
8 changes: 4 additions & 4 deletions yarn-project/archiver/src/archiver/eth_log_handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ async function getBlockFromCallData(
numToUInt32BE(Number(l2BlockNum)), // L2Block.archive.nextAvailableLeafIndex
Buffer.from(hexToBytes(bodyHex)),
]);
const block = L2Block.fromBufferWithLogs(blockBuffer);
const block = L2Block.fromBuffer(blockBuffer);
if (BigInt(block.number) !== l2BlockNum) {
throw new Error(`Block number mismatch: expected ${l2BlockNum} but got ${block.number}`);
}
Expand Down Expand Up @@ -177,20 +177,20 @@ export async function getContractDeploymentLogs(

/**
* Processes newly received ContractDeployment logs.
* @param blockHashMapping - A mapping from block number to relevant block hash.
* @param blockNumberToBodyHash - A mapping from block number to relevant body hash.
* @param logs - ContractDeployment logs.
* @returns The set of retrieved extended contract data items.
*/
export function processContractDeploymentLogs(
blockHashMapping: { [key: number]: Buffer | undefined },
blockNumberToBodyHash: { [key: number]: Buffer | undefined },
logs: Log<bigint, number, undefined, true, typeof ContractDeploymentEmitterAbi, 'ContractDeployment'>[],
): [ExtendedContractData[], number][] {
const extendedContractData: [ExtendedContractData[], number][] = [];
for (let i = 0; i < logs.length; i++) {
const log = logs[i];
const l2BlockNum = Number(log.args.l2BlockNum);
const blockHash = Buffer.from(hexToBytes(log.args.l2BlockHash));
const expectedBlockHash = blockHashMapping[l2BlockNum];
const expectedBlockHash = blockNumberToBodyHash[l2BlockNum];
if (expectedBlockHash === undefined || !blockHash.equals(expectedBlockHash)) {
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export class BlockStore {
void this.#txIndex.set(tx.txHash.toString(), [block.number, i]);
}

for (const [i, contractData] of block.newContractData.entries()) {
for (const [i, contractData] of block.body.txEffects.flatMap(txEffect => txEffect.contractData).entries()) {
if (contractData.contractAddress.isZero()) {
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,12 @@ export class ContractStore {
}

const block = this.#blockStore.getBlock(blockNumber);
return block?.newContractData[index];

if (block?.body.txEffects[index].contractData.length !== 1) {
throw new Error(`Contract data at block: ${blockNumber}, tx: ${index} does not have length of 1`);
}

return block?.body.txEffects[index].contractData[0];
}

/**
Expand All @@ -88,6 +93,6 @@ export class ContractStore {
*/
getContractDataInBlock(blockNumber: number): ContractData[] {
const block = this.#blockStore.getBlock(blockNumber);
return block?.newContractData ?? [];
return block?.body.txEffects.flatMap(txEffect => txEffect.contractData) ?? [];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe('MemoryArchiverStore', () => {

await archiverStore.addBlocks(blocks);
await Promise.all(
blocks.map(block => archiverStore.addLogs(block.newEncryptedLogs, block.newUnencryptedLogs, block.number)),
blocks.map(block => archiverStore.addLogs(block.body.encryptedLogs, block.body.unencryptedLogs, block.number)),
);

const response = await archiverStore.getUnencryptedLogs({});
Expand Down
Loading

0 comments on commit 081da3c

Please sign in to comment.