Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic transaction decompressor #180

Merged
merged 48 commits into from
Feb 8, 2024
Merged

Generic transaction decompressor #180

merged 48 commits into from
Feb 8, 2024

Conversation

Agusx1211
Copy link
Member

This decompressor contract can handle compressed sequence transactions; everything can be compressed (nonce, address, transactions, signature). The compression methods are:

  • Packing of data (remove extra 0s from ABI encoding)
  • References to duplicated data
  • Alternative representation of numbers (2**N, 2**N - 1, 10**N * X, etc.)
  • Known values (function signatures, transaction structure, etc.)
  • Cache data on contract storage (when calldata is more expensive than storage)

Current gas savings for compressed data are:

  • ~15% when used on L1s
  • ~50% when used on L2s

The decompressor is written in huff as it does not need to be trusted; it has no special permissions. It works as a state machine that has the only task of inflating the transactions.

It additionally can:

  • Execute many compressed transactions at once
  • Present the stored cache (to be used by a second version)
  • Decompress a transaction without executing it

Notice that, in an attempt to reduce gas costs, the contract does not have standard Solidity selectors; it instead only uses the first single byte as a selector. The following methods do exist:

  • 0x00: Decompress and execute a transaction
  • 0x01: Decompress and execute many transactions
  • 0x02: Read the cached address on index (takes 32 bytes as a parameter)
  • 0x03: Read the cached bytes32 on index (takes 32 bytes as a parameter)
  • 0x04: Returns the count of cached values (packed, uses 16 bytes for each)
  • 0x05: Reads N storage slots (takes 32 x N parameters, without size prefix)
  • 0x06: Decompress and return the execution data of a transaction
  • 0x07: Decompress and return the execution data of many transactions

Any other selector will lead to undefined behavior. Similarly, the contract uses CALLVALUE as a replacement for PUSH0, so it MUST be called with msg.value == 0; the contract does not validate it, sending funds to it will result in undefined behavior.

@pkieltyka pkieltyka merged commit 51d8c32 into master Feb 8, 2024
9 checks passed
@pkieltyka pkieltyka deleted the arbitrum-compressor branch February 8, 2024 01:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants