diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 627c49c..615884a 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -2,8 +2,8 @@ ## Data availability -Data availability is provided by L1 via posting the data as `calldata` to the `CTC` contract. -You can find the contract responsible for this in the [CanonicalTransactionChain.sol](./packages/contracts/src/CanonicalTransactionChain.sol). +Data availability is provided by L1 via posting the data as `calldata` to the `Inputs` contract. +You can find the contract responsible for this in the [Inputs.sol](./packages/contracts/src/Inputs.sol). It has a single function that can be called by anyone, and it's going to emit an event for easier retrieval of new batches. Users can either send transactions to the contract or the sequencer that is later going to call the same function. @@ -17,7 +17,7 @@ These addresses are considered to be faucets, if their supply runs out, there ar ### Data fetching Data is fetched by the [BatchDownloader.ts](./packages/node/src/core/BatchDownloader.ts), after it's downloaded, the `calldata` is extracted and passed through the State Transition Function by [StateUpdater.ts](./packages/node/src/core/StateUpdater.ts), the results are stored in the database. -BatchDownloader relies on the events emitted by the `CTC` to find all the necessary `calldata`. +BatchDownloader relies on the events emitted by the `Inputs` to find all the necessary `calldata`. ### State transition function @@ -52,4 +52,4 @@ Each sequencer has it's own mempool and transactions by default are sorted by th # Wallet / Frontend -The frontend is stored in [here](./packages/wallet/). \ No newline at end of file +The frontend is stored in [here](./packages/wallet/). diff --git a/README.md b/README.md index 9d84266..b514dc2 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Build Your Own Rollup - A simple rollup implementation for educational purposes. If you want to read the code and understand how it works you should start with the following files: -1. [The smart contract](./packages/contracts/src/CanonicalTransactionChain.sol) +1. [The smart contract](./packages/contracts/src/Inputs.sol) 2. [The node](./packages/node/src/index.ts) For more details about the architecture, see [here](./ARCHITECTURE.md). diff --git a/packages/contracts/scripts/deploy.ts b/packages/contracts/scripts/deploy.ts index f89bf5a..29ec81c 100644 --- a/packages/contracts/scripts/deploy.ts +++ b/packages/contracts/scripts/deploy.ts @@ -55,13 +55,11 @@ async function main(): Promise { await startPerpetualHardhatNode() } - const ctcFactory = await ethers.getContractFactory( - 'CanonicalTransactionChain', - ) - const ctc = await ctcFactory.deploy() - await ctc.deployed() + const inputsFactory = await ethers.getContractFactory('Inputs') + const inputs = await inputsFactory.deploy() + await inputs.deployed() - console.log(`CanonicalTransactionChain deployed to ${ctc.address}`) + console.log(`Inputs deployed to ${inputs.address}`) } main().catch((error) => { diff --git a/packages/contracts/src/Caller.sol b/packages/contracts/src/Caller.sol index 67a7719..7be30a3 100644 --- a/packages/contracts/src/Caller.sol +++ b/packages/contracts/src/Caller.sol @@ -1,17 +1,17 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import './CanonicalTransactionChain.sol'; +import './Inputs.sol'; // Only used for testing contract Caller { - CanonicalTransactionChain ctc; + Inputs inputs; - constructor(address ctcContract) { - ctc = CanonicalTransactionChain(ctcContract); + constructor(address inputsContract) { + inputs = Inputs(inputsContract); } function appendBatch(bytes calldata batch) public { - ctc.appendBatch(batch); + inputs.appendBatch(batch); } } diff --git a/packages/contracts/src/CanonicalTransactionChain.sol b/packages/contracts/src/Inputs.sol similarity index 91% rename from packages/contracts/src/CanonicalTransactionChain.sol rename to packages/contracts/src/Inputs.sol index 7fa917e..84a06b4 100644 --- a/packages/contracts/src/CanonicalTransactionChain.sol +++ b/packages/contracts/src/Inputs.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -contract CanonicalTransactionChain { +contract Inputs { event BatchAppended(address sender); function appendBatch(bytes calldata) external { diff --git a/packages/contracts/test/CanonicalTransactionChain.test.ts b/packages/contracts/test/Inputs.test.ts similarity index 62% rename from packages/contracts/test/CanonicalTransactionChain.test.ts rename to packages/contracts/test/Inputs.test.ts index 18eeacf..9f9cbde 100644 --- a/packages/contracts/test/CanonicalTransactionChain.test.ts +++ b/packages/contracts/test/Inputs.test.ts @@ -2,7 +2,7 @@ import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' import { assert, expect } from 'chai' import hre from 'hardhat' -describe('CanonicalTransactionChain', () => { +describe('Inputs', () => { const randomBytes = '0x12345678907654321234567890987654321234567890987654' async function getDeployer(): Promise { @@ -14,23 +14,19 @@ describe('CanonicalTransactionChain', () => { it('Should emit BatchAppended event', async () => { const deployer = await getDeployer() - const ctcFactory = await hre.ethers.getContractFactory( - 'CanonicalTransactionChain', - ) - const ctc = await ctcFactory.deploy() + const inputsFactory = await hre.ethers.getContractFactory('Inputs') + const inputs = await inputsFactory.deploy() - await expect(ctc.appendBatch(randomBytes)) - .to.emit(ctc, 'BatchAppended') + await expect(inputs.appendBatch(randomBytes)) + .to.emit(inputs, 'BatchAppended') .withArgs(await deployer.getAddress()) }) it('Should revert if called from another contract', async () => { - const ctcFactory = await hre.ethers.getContractFactory( - 'CanonicalTransactionChain', - ) - const ctc = await ctcFactory.deploy() + const inputsFactory = await hre.ethers.getContractFactory('Inputs') + const inputs = await inputsFactory.deploy() const callerFactory = await hre.ethers.getContractFactory('Caller') - const caller = await callerFactory.deploy(ctc.address) + const caller = await callerFactory.deploy(inputs.address) await expect(caller.appendBatch(randomBytes)).to.be.reverted }) diff --git a/packages/node/src/core/BatchPoster.test.ts b/packages/node/src/core/BatchPoster.test.ts index 10a95aa..0293dc2 100644 --- a/packages/node/src/core/BatchPoster.test.ts +++ b/packages/node/src/core/BatchPoster.test.ts @@ -88,7 +88,7 @@ describe(BatchPoster.name, () => { }), }) const client = mockObject({ - writeToCTCContract: mockFn().returns(null), + writeToInputsContract: mockFn().returns(null), }) const mempool = mockObject({ popNHighestFee: mockFn() @@ -109,12 +109,12 @@ describe(BatchPoster.name, () => { expect(mempool.empty).toHaveBeenCalledTimes(0) expect(mempool.popNHighestFee).toHaveBeenCalledTimes(2) - expect(client.writeToCTCContract).toHaveBeenCalledTimes(2) - expect(client.writeToCTCContract).toHaveBeenNthCalledWith( + expect(client.writeToInputsContract).toHaveBeenCalledTimes(2) + expect(client.writeToInputsContract).toHaveBeenNthCalledWith( 1, modelTx1SerializedHex, ) - expect(client.writeToCTCContract).toHaveBeenNthCalledWith( + expect(client.writeToInputsContract).toHaveBeenNthCalledWith( 2, modelTx2SerializedHex, ) @@ -145,7 +145,7 @@ describe(BatchPoster.name, () => { }), }) const client = mockObject({ - writeToCTCContract: mockFn().returns(null), + writeToInputsContract: mockFn().returns(null), }) const mempool = mockObject({ popNHighestFee: mockFn() @@ -166,8 +166,8 @@ describe(BatchPoster.name, () => { expect(mempool.empty).toHaveBeenCalledTimes(0) expect(mempool.popNHighestFee).toHaveBeenCalledTimes(2) - expect(client.writeToCTCContract).toHaveBeenCalledTimes(1) - expect(client.writeToCTCContract).toHaveBeenNthCalledWith( + expect(client.writeToInputsContract).toHaveBeenCalledTimes(1) + expect(client.writeToInputsContract).toHaveBeenNthCalledWith( 1, modelTx1SerializedHex, ) @@ -198,7 +198,7 @@ describe(BatchPoster.name, () => { }), }) const client = mockObject({ - writeToCTCContract: mockFn().returns(null), + writeToInputsContract: mockFn().returns(null), }) const mempool = mockObject({ popNHighestFee: mockFn() @@ -219,7 +219,7 @@ describe(BatchPoster.name, () => { expect(mempool.empty).toHaveBeenCalledTimes(0) expect(mempool.popNHighestFee).toHaveBeenCalledTimes(2) - expect(client.writeToCTCContract).toHaveBeenCalledTimes(0) + expect(client.writeToInputsContract).toHaveBeenCalledTimes(0) }) it('does not submit empty transactions', async () => { @@ -247,7 +247,7 @@ describe(BatchPoster.name, () => { }), }) const client = mockObject({ - writeToCTCContract: mockFn().returns(null), + writeToInputsContract: mockFn().returns(null), }) const mempool = mockObject({ popNHighestFee: mockFn() @@ -269,12 +269,12 @@ describe(BatchPoster.name, () => { expect(mempool.empty).toHaveBeenCalledTimes(0) expect(mempool.popNHighestFee).toHaveBeenCalledTimes(3) - expect(client.writeToCTCContract).toHaveBeenCalledTimes(2) - expect(client.writeToCTCContract).toHaveBeenNthCalledWith( + expect(client.writeToInputsContract).toHaveBeenCalledTimes(2) + expect(client.writeToInputsContract).toHaveBeenNthCalledWith( 1, modelTx1SerializedHex, ) - expect(client.writeToCTCContract).toHaveBeenNthCalledWith( + expect(client.writeToInputsContract).toHaveBeenNthCalledWith( 2, modelTx2SerializedHex, ) @@ -305,7 +305,7 @@ describe(BatchPoster.name, () => { }), }) const client = mockObject({ - writeToCTCContract: mockFn().returns(null), + writeToInputsContract: mockFn().returns(null), }) const mempool = mockObject({ popNHighestFee: mockFn() @@ -326,7 +326,7 @@ describe(BatchPoster.name, () => { expect(mempool.empty).toHaveBeenCalledTimes(0) expect(mempool.popNHighestFee).toHaveBeenCalledTimes(2) - expect(client.writeToCTCContract).toHaveBeenCalledTimes(0) + expect(client.writeToInputsContract).toHaveBeenCalledTimes(0) }) it('does not submit transaction if balance if nonce is wrong', async () => { @@ -354,7 +354,7 @@ describe(BatchPoster.name, () => { }), }) const client = mockObject({ - writeToCTCContract: mockFn().returns(null), + writeToInputsContract: mockFn().returns(null), }) const mempool = mockObject({ popNHighestFee: mockFn() @@ -375,7 +375,7 @@ describe(BatchPoster.name, () => { expect(mempool.empty).toHaveBeenCalledTimes(0) expect(mempool.popNHighestFee).toHaveBeenCalledTimes(2) - expect(client.writeToCTCContract).toHaveBeenCalledTimes(0) + expect(client.writeToInputsContract).toHaveBeenCalledTimes(0) }) it('submits transactions every flush period seconds', async () => { @@ -403,7 +403,7 @@ describe(BatchPoster.name, () => { }), }) const client = mockObject({ - writeToCTCContract: mockFn() + writeToInputsContract: mockFn() .throwsOnce(new Error('failed')) .returns(null), }) @@ -426,12 +426,12 @@ describe(BatchPoster.name, () => { expect(mempool.empty).toHaveBeenCalledTimes(0) expect(mempool.popNHighestFee).toHaveBeenCalledTimes(2) - expect(client.writeToCTCContract).toHaveBeenCalledTimes(2) - expect(client.writeToCTCContract).toHaveBeenNthCalledWith( + expect(client.writeToInputsContract).toHaveBeenCalledTimes(2) + expect(client.writeToInputsContract).toHaveBeenNthCalledWith( 1, modelTx1SerializedHex, ) - expect(client.writeToCTCContract).toHaveBeenNthCalledWith( + expect(client.writeToInputsContract).toHaveBeenNthCalledWith( 2, modelTx2SerializedHex, ) diff --git a/packages/node/src/core/BatchPoster.ts b/packages/node/src/core/BatchPoster.ts index 18f07a6..2d0b984 100644 --- a/packages/node/src/core/BatchPoster.ts +++ b/packages/node/src/core/BatchPoster.ts @@ -51,7 +51,7 @@ export class BatchPoster { } const batchBytes = serializeBatch(validTransactions) - await this.client.writeToCTCContract(batchBytes) + await this.client.writeToInputsContract(batchBytes) this.logger.info('Submitted', { count: candidateTransactions.length, leftInMempool: this.mempool.size(), diff --git a/packages/node/src/peripherals/ethereum/EthereumPrivateClient.test.ts b/packages/node/src/peripherals/ethereum/EthereumPrivateClient.test.ts index 1b30ed4..0279ab6 100644 --- a/packages/node/src/peripherals/ethereum/EthereumPrivateClient.test.ts +++ b/packages/node/src/peripherals/ethereum/EthereumPrivateClient.test.ts @@ -7,8 +7,8 @@ import { abi } from '../../core/abi' import { EthereumPrivateClient } from './EthereumPrivateClient' describe(EthereumPrivateClient.name, () => { - describe(EthereumPrivateClient.prototype.writeToCTCContract.name, () => { - it('writes data to the CTC contract using private provider', async () => { + describe(EthereumPrivateClient.prototype.writeToInputsContract.name, () => { + it('writes data to the Inputs contract using private provider', async () => { const publicProvider = mockObject({}) const privateProvider = mockObject({ writeContract: mockFn().returnsOnce(''), @@ -25,7 +25,7 @@ describe(EthereumPrivateClient.name, () => { Logger.SILENT, ) - await ethereumClient.writeToCTCContract(Hex('0x1234')) + await ethereumClient.writeToInputsContract(Hex('0x1234')) expect(privateProvider.writeContract).toHaveBeenCalledWith({ address: ctcContractAddress.toString(), diff --git a/packages/node/src/peripherals/ethereum/EthereumPrivateClient.ts b/packages/node/src/peripherals/ethereum/EthereumPrivateClient.ts index 611063f..ea5bf28 100644 --- a/packages/node/src/peripherals/ethereum/EthereumPrivateClient.ts +++ b/packages/node/src/peripherals/ethereum/EthereumPrivateClient.ts @@ -16,7 +16,7 @@ export class EthereumPrivateClient extends EthereumClient { this.logger = this.logger.for(this) } - async writeToCTCContract(batchBytes: Hex): Promise { + async writeToInputsContract(batchBytes: Hex): Promise { await this.privateProvider.writeContract({ address: this.ctcContractAddress.toString(), abi: abi,