gakonst / ethers-rs

Complete Ethereum & Celo library and wallet implementation in Rust. https://docs.rs/ethers
Apache License 2.0
2.51k stars 794 forks source link

Support for EIP-4844 Shard Blob Transaction #1742

Open AbdelStark opened 2 years ago

AbdelStark commented 2 years ago

Context

EIP-4844 introduces a new transaction type, using EIP-2718 mechanism.

As @gakonst mentioned:

Separately, I'd love to spend some cycles thinking how EIP4844 transactions could be added to Ethers as a new EIP2718 type. https://www.eip4844.com/

Originally posted by @gakonst in https://github.com/gakonst/ethers-rs/issues/1685#issuecomment-1243048983

Feature

Implement a new transaction type in ethers-rs to enable developers to use shard blob transactions.

According to the EIP specification, the new transaction type encoding is the following:

class SignedBlobTransaction(Container):
    message: BlobTransaction
    signature: ECDSASignature

class BlobTransaction(Container):
    chain_id: uint256
    nonce: uint64
    priority_fee_per_gas: uint256
    max_basefee_per_gas: uint256
    gas: uint64
    to: Union[None, Address] # Address = Bytes20
    value: uint256
    data: ByteList[MAX_CALLDATA_SIZE]
    access_list: List[AccessTuple, MAX_ACCESS_LIST_SIZE]
    blob_versioned_hashes: List[VersionedHash, MAX_VERSIONED_HASHES_LIST_SIZE]

class AccessTuple(Container):
    address: Address # Bytes20
    storage_keys: List[Hash, MAX_ACCESS_LIST_STORAGE_KEYS]

class ECDSASignature(Container):
    y_parity: boolean
    r: uint256
    s: uint256

SSZ encoding

The new transaction is then: a single byte BLOB_TX_TYPE (0x05) followed by an SSZ encoding of the SignedBlobTransaction container.

It means that ethers-rs needs a way to encode and decode using SSZ format. As far as I know, currently there is no way to use SSZ encoding. We should then think about how we want to add this encoding, some alternatives:

Open design questions

External implementations and tooling

There is currently a Devnet v1 running with a Geth fork for the EL and a Prysm fork for the CL.

Geth

For the Geth fork this is the implementation of shard blob transactions: see data_blob_tx.go

blob-utils

blob-utils is a CLI tool to send and download blobs on the proto-danksharding devnet.

gakonst commented 2 years ago

Could you share a couple test vectors? I could work on a branch that does that, just would like to ensure I get the serialization right. I like the idea of using ssz-rs.

AbdelStark commented 2 years ago

Could you share a couple test vectors? I could work on a branch that does that, just would like to ensure I get the serialization right. I like the idea of using ssz-rs.

Please find a sample JSON file with test vectors here: eip4844_test_vectors_sample_1.json

The code to generate the sample is also available here: test-vectors

To generate new test vectors you can:

go test

Discord: https://discord.com/channels/595666850260713488/595701195843174434/1024344939959697498

gakonst commented 2 years ago

Sweet. Will give a shot by this weekend.

gakonst commented 2 years ago

Dived into this, rough notes below. The biggest thing we're missing is a Rust function for blobs.ComputeCommitmentsAndAggregatedProof(). Everything else is basic type defs and conversions.

Generating a proof will mean we need to also have the KZG G1 trusted setup parameters loaded. Presumably these would be loaded via the Provider/SignerMiddleware, and we could consider distributing them with the library as an optional feature.

ethers-rs / eip4844 changes

  1. Find Rust KZG library which exposes what we need https://github.com/mdehoog/go-ethereum/blob/e5291efded799e80f6e8b77f21b45fa6bbc0b2d3/core/types/data_blob.go#L353-L398

  2. Figure out how to SSZ serialize https://github.com/mdehoog/go-ethereum/commit/fce14ba9348950e746c712081dbd9c3fa99bd2c5#diff-d32f17b8a6d7109add632096d016f4cb111673ad2168034ecbced8af07d77822R517

https://github.com/Inphi/eip4844-interop/pull/28/files#diff-8f4c9db42d0333036ce672478a2c1d190b9257f8277759f9f3b2985c1a01a3d6R63

  1. new transaction type After confirmed -> Option? Like we do for BaseFee. https://github.com/mdehoog/go-ethereum/blob/e5291efded799e80f6e8b77f21b45fa6bbc0b2d3/core/types/data_blob_tx.go#L318

              BlobVersionedHashes: versionedHashes,

    Submit with KZG Proof on new tx type https://github.com/Inphi/blob-utils/blob/4fab45306c1406e122a12cb7c0f0d28bb8a69afa/utils.go#L14-L50 https://github.com/Inphi/eip4844-interop/blob/master/shared/blobs.go#L9-L45

    blobs := shared.EncodeBlobs(data) commitments, versionedHashes, aggregatedProof, err := blobs.ComputeCommitmentsAndAggregatedProof()

    How to pass the trusted setup? Add it as a builder-pattern parameter to the provider? And to the signer?

  2. new header field https://github.com/mdehoog/go-ethereum/blob/eip-4844/core/types/block.go#L91-L92 excess_blobs (camelcase)

  3. test it out against prod https://github.com/Inphi/eip4844-interop/blob/69392f4ff7d6339dabcd9cb1f4bf65d4480f9600/tests/fee-market/main.go https://github.com/Inphi/blob-utils/blob/4fab45306c1406e122a12cb7c0f0d28bb8a69afa/download.go

Misc:

gakonst commented 2 years ago

We might be able to use this library for the proof / commitments gen https://github.com/crate-crypto/proto-danksharding-crypto/tree/master/crypto

Inphi commented 2 years ago

For ssz seralize, lighthouse's internal ssz crate is worth looking into as it's battle tested and used on mainnet. It's a self contained package that doesn't depend on any lighthouse modules, so it can easily be included in ethers-rs. It's missing a few things for EIP-4844, like a Bytes48 ssz codec and hash_tree_root implementation needed for KZG commitments.

gakonst commented 2 years ago

Flagging @asn-d6's library too https://github.com/asn-d6/blobbers

koloz193 commented 12 months ago

Any update on this? With 4844 approaching this seems like something that would be helpful