# TX rollup design Rollups proceed in blocks, just like L1. L1 needs to know when rollup blocks are final, so that it can apply their L1 effects. A L1 block is final 30 blocks after its first non-rejected commitment is received. So L1 needs to store all commitments until either they are rejected, or they are final. A block is broken into batches of operations to reduce the size of commitment rejections. ## L1 Storage (per rollup): - Commitment table - key: Rollup address * Commitment hash = H(data excluding committer account id) - Because the commitment key does not include the account id, we can reject duplicate commitments before storing them. - value Commitment - committer account id - ancestor commitment hash - (effect list * after root) list - each entry is one batch - Candidates table - key: Rollup address * Rollup level (that the commitment applies to) - value: - (Commitment hash) list - Tezos level for finalization - Inbox - key: Rollup address * Rollup level - value: - (rollup-operation list) list - Ticket ledger - key: Ticket hash (= H (ticketer, content, type)) - value : ticketer, content, type, amount Note: - Nodes must store the rollup operation batches so that we can replay them in the event of a rejection. Once a commitment to a block is final, we no longer need to retain these. - If amount = 0, then an entry can be removed from the ticket values table ## L1 operations: (including gas and fees) [Chiachi: I added some details [here](https://hackmd.io/XfjDXcL-SFSAAQprpFZ54w?both) but I havn't finished it yet.] - Create rollup: creates a rollup identified by a hash of the operation - This burns 100 tez, which is somewhat arbitrary, but which should be sufficient to reduce unnecessary rollup creation - Append: append a L2 operation to a rollup - No gas cost beyond the storage - Deposit: transfer tickets to a rollup - ?? gas cost ?? - Commitment: commit to a rollup block - Contents: - rollup id - rollup level - committer account id - ancestor commitment hash - (effect list * after root) list - Requires a deposit of 10,000 tz - Probably no need for gas cost given the deposit requirement - Rejection: - Key: commitment hash * batch index * H(after_root, effects) (earliest batch index is checked first; after a successful rejection, subsequent rejections of the same commitment hash get no reward) - Value: - rejector account id - commitment hash - batch index - after root - effect list - Requires a deposit - Gets a reward on success ## L2 storage (per rollup): - Part of the shared hash (sent to the L1 in commitments) - Counter (anti-replay) table, per-account - key: account - value: Z - Ticket table (per-account) - key: account * ticket_hash - value: Z - Maintained by rollup node only - Rollup block table - key: rollup block hash (?) - value: We need a notion of rollup blocks - L2 operation hashes - L2 operation receipts (`Applied`, `Rejected`) ## L2 operations: - operations (signed by an account, and comes with a counter): - Transfer (ticket from the signer to an account) - account id to - ticket hash - amount - (TODO in MR 4) Burn (part of withdraw) - “trades”: a list of operations to be executed atomically (maybe be a list of 1 element). It is signed by the origin account of each individual operation - batch: a list of “trades”, with an aggregated signature for each of the trade Proposed approach to carbonate: - For the BLS, fixed cost * number of signature to check - If failure, then the all batch is a no-op, and operations can be resubmitted in a smaller batch - For IO, fixed cost * (number of bytes of the key + number of expected bytes of the value, since (if?) of values are of fixed size) - The `Counter` table is not carbonated - If failure, the counters are incremented and therefore the operations cannot be resubmitted Pros: - Easy to provide a upper-bound - We can implement a `simulate` RPC in the rollup node to mimic how it is done in L1