EIP-4844: Shard Blob Transactions

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

Nice to see that the new transaction format replaces the RLP transaction encoding with SSZ and moves chain_id to be a field allowing for using boolean for `y_parity.

There’s potential for some optimisation here at the expensive of some clarity: EIP-2098: Compact Signature Representation

Was this discussed yet?

Edit: the parity field seems to have a 1 byte overhead so this is neglible.

intrinsic_gas = 20000  # G_transaction, previously 21000

If the intent is to change G_transaction from 21000 to 20000 that should be a separate EIP that includes rationale for the change just like every other gas cost change.

If the intent is to have this specific transaction type have a different intrinsic cost from other transactions then this EIP should include rationale on why these transactions have a lower base operational overhead than other types of transactions.

If the intent is to try to incentivize certain behaviors, we should not be hijacking our operational cost pricing mechanism to try to achieve that.

Went ahead and reverted that change: fix(4844): leave G_transaction at 21000 by gakonst · Pull Request #5636 · ethereum/EIPs · GitHub

1 Like

Great proposal! Quick question, @protolambda , why does the signature cover the blob-data, instead of only covering the commitment(s) to the blob-data? It seems that for Danksharding, validators will not be receiving all of the blobs (only the commitments), yet they’ll still have to verify the signatures.

I made this for myself, just so I can anticipate what this will do to the nodes running on my machines. Sorry for any mistakes. I’ll correct it if there are any. Please let me know.

Thought I’d share:

Can we add something like below from 2718 to the beginning of the specification section to define the || operator? It’s used in several places in the EIP and can be interpreted in a variety of ways, depending on which programming language(s) one happens to be familiar with.

Definitions

  • || is the byte/byte-array concatenation operator.

Moving the discussion from Clarify & rationalize blob transaction hash computations in EIP-4844 · Issue #6245 · ethereum/EIPs · GitHub here.

  • Enable 0-blob transactions to use SSZ format: On devp2p eth/68, 4844 suggests that the EIP-2718 transaction type is advertised to indicate Gossip and mempool behaviour. The EIP-2718 transaction type should solely be used to (1) denote the serialization format of a tx on the wire (also, as part of GetBlockBodys), (2) for the purpose of signing, and (3) for deriving the transaction hash. Giving it mempool specific meaning leads to problems and unnecessary discussions, e.g., for the 0-blob transaction case. It would be preferrable to advertise the number (or presence) of blobs instead of the transaction type on eth/68. Type 5 based 0-blob transactions could then be prossed the same as any type 0x01, 0x02, or 0xc0-0xfe transactions; Transactions with blobs (of type 0x05, or any future types that also have blobs) would use the req/resp based solution using the network wrapper.

  • SSZ encoding: EIP-6475: SSZ Optional SSZ Optional[Address] is preferrable over Union[None, Address], as it makes the SSZ merkle tree shape static, meaning that proof requests including the address can’t randomly fail based on union selector. Note that for fixed length items such as Address, Optional[Address] is equivalent to List[Address, 1] for the purpose of SSZ serialization and merkleization.

  • Constant tuning: MAX_VERSIONED_HASHES_LIST_SIZE is matching the maximum number of blobs per transaction, and is currently set to 16 million. This exceeds any rational design space; keep in mind that SSZ serialization caps out at 4 GB, so such transactions could not even be serialized. If devp2p eth/68 is updated to indicate the number of blobs, note that this number also is part of the advertisement and making it fit into a uint8 or uint16 may be desirable.

There’s been ongoing discussion around mempool DoS concerns, so perhaps we can start adding more recommendations to the spec around mempool handling of blob txs. Right now the spec suggests increasing data gas price by at least 10% for replacement, and the mempool already requires increasing regular gas price by 10% for replacement. Additional constraints that prevent specific DoS scenarios without being too burdensome on clients include:

  • Blob-holding txs should only be replaced by blob txs consuming at least as much datagas (e.g. # of blobs can never decrease). This prevents mempools from being spammed with multiple-blob txs to have them later deleted by (much cheaper) 0 or 1 blob txs.

  • There can only be one blob-containing tx per account. This prevents someone from spamming the mempool with multiple blob-holding txs each with sequential nonces in a way where none of them beyond the first would successfully execute & incur fees.

The suggestion from Etan in a comment above around announcing # of blobs in eth/68 instead of tx type would also help mempools better deal with blob-related DoS risk.

1 Like

Made a concrete proposal for eth/68 changes here:

For SSZ Optional, opened a PR:

1 Like

Re: data blob transaction replacement. From today’s 4844 client devs call, Dankrad noted that requiring increasing data gas (whether 10 or 100%) for blob tx replacement may not be a suitable disincentive for DoS since the gas is priced using 1559-type rules.

Ansgar suggested we might then also require that replacement txs contain the exact blob as before (so it would not have to be reverified). Depending on if it’s important, we could also allow replacement txs to add additional blobs, though this may be too much of an edge case to worry about.

Hey I just noticed that EIP-4844 doesn’t actually specify the ReceiptPayload format anywhere and probably should. For example EIP-1559 includes the line:

The EIP-2718 ReceiptPayload for this transaction is rlp([status, cumulative_transaction_gas_used, logs_bloom, logs])

But, before we add the ReceiptPayload I’m curious what others think of this idea I expressed on the ACD discord, where we remove the logs_bloom field from type 0x5 tx receipts? As discussed over there, most tx receipts only include a single event if any, so dedicating a full 256 bytes to the logs_bloom in the tx receipt feels a bit heavy (if the number of events in a tx receipt is small, it’s probably more effecient to just go ahead and scan the events vs. using the bloom since you have to scan the events anyways to double check against false positives in the bloom filter).

2 Likes

Re: Receipts, it was also noted in discord during the workshop that we should return dataGasUsed as part of the non-consensus receipt values.

On today’s 4844 client devs call, Marius from geth suggested we consider making the blob tx type more specialized, e.g. by removing access list and ability to create contracts. Wanted to open that up for discussion here. Does anyone have any concrete use cases for access lists and/or contracts in blob txs?

PEEPanEIP-4844: Shard Blob Transactions with Terence & Kasey

I know it’s kind of the Ethereum convention to add new cryptographic primitives as precompiles, but why? Why does the kzg point evaluation function have to be called via this round-about way using memory + staticcall?

There’s almost a full “row” of EVM instructions (0x21-0x2f) that have remained unclaimed so far and that could be allocated to important functions such as those required for this EIP.

Opcodes 0x21-0x26 are planned to be claimed by EVMMAX (EIP-6601) so 0x27 might be a good next candidate for point_evaluation function with similar semantics, popping 6 EVM words from the stack for the function and pushing the returndata.

Another question I have is why the function is returning constants and not a success flag / nothing. What’s the intention behind the function returning two constants?

2 Likes

Hi all, thanks all for working on this proposal

I got a question from an app developer point of view.

the proposal does not seem to specify any api to consume the data

It says

This EIP introduces a transaction type that has a distinct mempool version and execution-payload version, with only one-way convertibility between the two. The blobs are in the network representation and not in the consensus representation; instead, they are coupled with the beacon block. This means that there is now a part of a transaction that will not be accessible from the web3 API.

If i understand correctly it means the actual blob data is not directly available to execution client and as such these cannot provide it, but the consensus client can. Am I right here?

Furthermore it means that the execution client still have access to some data, is that the commitment and so a reference to the blob ?

it would be great if the eip would specify the api for what is available both for the execution client and consensus client. It seems to me that the EIP would not be complete without these. Or maybe there is another EIP that deals with that ?

Also i am wondering if is possible for the execution client to still provide the blob data api by simply forwarding the request to consensus client.

Note that my perspective is that of a app developer that is potentially interested to make use of EIP-4844 to retrieve data from the blobs by calling the user’s wallet rpc endpoint (EIP-1193) and so I am interested to know what this proposal will allow the user to fetch.,

Please correct me if any of my assumption are wrong

Thanks

2 Likes

There is a beacon-API that can be used to access blob sidecars. The client needs to be configured with both an execution-API and beacon-API provider.

https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/getBlobSidecars

1 Like

Hi. From the spec it’s not clear to me what is exactly the blob_versioned_hash. It’s supposed to start with VERSIONED_HASH_VERSION_KZG byte, initially set to 1. Does this mean that the hash is 33 bytes long? And second question if the blob_versioned_hash does not start with version byte is the transaction considered as invalid and sender balance remains unchanged or something opposite, data_fee is deducted from sender balance and burned?

LIMIT_BLOBS_PER_TX is currently defined in Parameters, but not used.