From c0e230d170d96d32356bb4edf2393093fb290d3b Mon Sep 17 00:00:00 2001 From: Alex Gherghisan Date: Mon, 15 Jan 2024 15:36:43 +0000 Subject: [PATCH 1/2] fix: do not publish empty contract data --- .../src/sequencer/sequencer.test.ts | 50 ++++++++++++++++++- .../src/sequencer/sequencer.ts | 27 +++++----- 2 files changed, 61 insertions(+), 16 deletions(-) diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts index 799ec870bd9..1bc34c9dc69 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts @@ -1,4 +1,13 @@ -import { L1ToL2MessageSource, L2Block, L2BlockSource, MerkleTreeId, Tx, TxHash, mockTx } from '@aztec/circuit-types'; +import { + ExtendedContractData, + L1ToL2MessageSource, + L2Block, + L2BlockSource, + MerkleTreeId, + Tx, + TxHash, + mockTx, +} from '@aztec/circuit-types'; import { BlockHeader, Fr, @@ -209,6 +218,45 @@ describe('sequencer', () => { expect(publisher.processL2Block).not.toHaveBeenCalled(); }); + + it('publishes contract data', async () => { + const txWithContract = mockTx(0x10000); + (txWithContract.newContracts as Array) = [ExtendedContractData.random()]; + txWithContract.data.constants.txContext.chainId = chainId; + + const txWithEmptyContract = mockTx(0x20000); + (txWithEmptyContract.newContracts as Array) = [ExtendedContractData.empty()]; + txWithEmptyContract.data.constants.txContext.chainId = chainId; + + const block = L2Block.random(lastBlockNumber + 1); + const proof = makeEmptyProof(); + + p2p.getTxs.mockResolvedValueOnce([txWithContract, txWithEmptyContract]); + blockBuilder.buildL2Block.mockResolvedValueOnce([block, proof]); + publisher.processL2Block.mockResolvedValueOnce(true); + publisher.processNewContractData.mockResolvedValueOnce(true); + globalVariableBuilder.buildGlobalVariables.mockResolvedValueOnce( + new GlobalVariables(chainId, version, new Fr(lastBlockNumber + 1), Fr.ZERO), + ); + + await sequencer.initialSync(); + await sequencer.work(); + + // check that the block was built with both transactions + expect(blockBuilder.buildL2Block).toHaveBeenCalledWith( + expect.anything(), + expect.arrayContaining([ + expect.objectContaining({ hash: await txWithContract.getTxHash() }), + expect.objectContaining({ hash: await txWithEmptyContract.getTxHash() }), + ]), + expect.any(Array), + ); + + // check that the empty contract did not get published + expect(publisher.processNewContractData).toHaveBeenCalledWith(block.number, block.getCalldataHash(), [ + txWithContract.newContracts[0], + ]); + }); }); class TestSubject extends Sequencer { diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.ts index bbb9a6af75c..e88d49deaf2 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.ts @@ -235,21 +235,18 @@ export class Sequencer { protected async publishExtendedContractData(validTxs: ProcessedTx[], block: L2Block) { // Publishes contract data for txs to the network and awaits the tx to be mined this.state = SequencerState.PUBLISHING_CONTRACT_DATA; - const newContractData = validTxs - .map(tx => { - // Currently can only have 1 new contract per tx - return tx.newContracts[0]; - }) - .filter((cd): cd is Exclude => cd !== undefined); - - const blockHash = block.getCalldataHash(); - this.log(`Publishing extended contract data with block hash ${blockHash.toString('hex')}`); - - const publishedContractData = await this.publisher.processNewContractData(block.number, blockHash, newContractData); - if (publishedContractData) { - this.log(`Successfully published new contract data for block ${block.number}`); - } else if (!publishedContractData && newContractData.length) { - this.log(`Failed to publish new contract data for block ${block.number}`); + const newContracts = validTxs.flatMap(tx => tx.newContracts).filter(cd => !cd.isEmpty()); + + if (newContracts.length > 0) { + const blockHash = block.getCalldataHash(); + this.log.info(`Publishing ${newContracts.length} contracts in block hash ${blockHash.toString('hex')}`); + + const publishedContractData = await this.publisher.processNewContractData(block.number, blockHash, newContracts); + if (publishedContractData) { + this.log(`Successfully published new contract data for block ${block.number}`); + } else if (!publishedContractData && newContracts.length) { + this.log(`Failed to publish new contract data for block ${block.number}`); + } } } From fbf6542aa0613003b9945cb4e2c67c25066b6cbe Mon Sep 17 00:00:00 2001 From: Alex Gherghisan Date: Tue, 16 Jan 2024 14:32:32 +0000 Subject: [PATCH 2/2] refactor: invert if check --- .../src/sequencer/sequencer.ts | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.ts index e88d49deaf2..f23c8c9a9df 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.ts @@ -237,16 +237,24 @@ export class Sequencer { this.state = SequencerState.PUBLISHING_CONTRACT_DATA; const newContracts = validTxs.flatMap(tx => tx.newContracts).filter(cd => !cd.isEmpty()); - if (newContracts.length > 0) { - const blockHash = block.getCalldataHash(); - this.log.info(`Publishing ${newContracts.length} contracts in block hash ${blockHash.toString('hex')}`); - - const publishedContractData = await this.publisher.processNewContractData(block.number, blockHash, newContracts); - if (publishedContractData) { - this.log(`Successfully published new contract data for block ${block.number}`); - } else if (!publishedContractData && newContracts.length) { - this.log(`Failed to publish new contract data for block ${block.number}`); - } + if (newContracts.length === 0) { + this.log.debug(`No new contracts to publish in block ${block.number}`); + return; + } + + const blockCalldataHash = block.getCalldataHash(); + this.log.info(`Publishing ${newContracts.length} contracts in block ${block.number}`); + + const publishedContractData = await this.publisher.processNewContractData( + block.number, + blockCalldataHash, + newContracts, + ); + + if (publishedContractData) { + this.log(`Successfully published new contract data for block ${block.number}`); + } else if (!publishedContractData && newContracts.length) { + this.log(`Failed to publish new contract data for block ${block.number}`); } }