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

EIP-4844: Implement NetworkTransactionPayload #1422

Closed
jangko opened this issue Jan 11, 2023 · 1 comment · Fixed by #1440
Closed

EIP-4844: Implement NetworkTransactionPayload #1422

jangko opened this issue Jan 11, 2023 · 1 comment · Fixed by #1440
Labels

Comments

@jangko
Copy link
Contributor

jangko commented Jan 11, 2023

Nodes must not automatically broadcast blob transactions to their peers. Instead, those transactions are only announced using NewPooledTransactionHashes messages, and can then be manually requested via GetPooledTransactions.

Transactions are presented as TransactionType || TransactionNetworkPayload on the execution layer network, the payload is a SSZ encoded container:

MAX_TX_WRAP_KZG_COMMITMENTS: 2 ** 24
FIELD_ELEMENTS_PER_BLOB: 4096
LIMIT_BLOBS_PER_TX: 2 ** 24

class BlobTransactionNetworkWrapper(Container):
    tx: SignedBlobTransaction
    # KZGCommitment = Bytes48
    blob_kzgs: List[KZGCommitment, MAX_TX_WRAP_KZG_COMMITMENTS]
    # BLSFieldElement = uint256
    blobs: List[Vector[BLSFieldElement, FIELD_ELEMENTS_PER_BLOB], LIMIT_BLOBS_PER_TX]
    # KZGProof = Bytes48
    kzg_aggregated_proof: KZGProof

We do network-level validation of BlobTransactionNetworkWrapper objects as follows:

def validate_blob_transaction_wrapper(wrapper: BlobTransactionNetworkWrapper):
    versioned_hashes = wrapper.tx.message.blob_versioned_hashes
    commitments = wrapper.blob_kzgs
    blobs = wrapper.blobs
    # note: assert blobs are not malformatted
    assert len(versioned_hashes) == len(commitments) == len(blobs)

    # Verify that commitments match the blobs by checking the KZG proof
    assert verify_aggregate_kzg_proof(blobs, commitments, wrapper.kzg_aggregated_proof)

    # Now that all commitments have been verified, check that versioned_hashes matches the commitments
    for versioned_hash, commitment in zip(versioned_hashes, commitments):
        assert versioned_hash == kzg_to_versioned_hash(commitment)

EIP-2718 is extended with a “wrapper data”, the typed transaction can be encoded in two forms, dependent on the context:

Network (default): TransactionType || TransactionNetworkPayload, or LegacyTransaction
Minimal (as in execution payload): TransactionType || TransactionPayload, or LegacyTransaction

Execution-payloads / blocks use the minimal encoding of transactions. In the transaction-pool and local transaction-journal the network encoding is used.

For previous types of transactions the network encoding is no different, i.e. TransactionNetworkPayload == TransactionPayload.

The TransactionNetworkPayload wraps a TransactionPayload with additional data: this wrapping data SHOULD be verified directly before or after signature verification.

When a blob transaction is passed through the network (see the Networking section below), the TransactionNetworkPayload version of the transaction also includes blobs and kzgs (commitments list). The execution layer verifies the wrapper validity against the inner TransactionPayload after signature verification as:

All hashes in blob_versioned_hashes must start with the byte BLOB_COMMITMENT_VERSION_KZG
There may be at most MAX_DATA_GAS_PER_BLOCK // DATA_GAS_PER_BLOB total blob commitments in a valid block.
There is an equal amount of versioned hashes, kzg commitments and blobs.
The KZG commitments hash to the versioned hashes, i.e. kzg_to_versioned_hash(kzg[i]) == versioned_hash[i]
The KZG commitments match the blob contents. (Note: this can be optimized with additional data, using a proof for a random evaluation at two points derived from the commitment and blob data)

BLOB_COMMITMENT_VERSION_KZG: Bytes1(0x01)
MAX_DATA_GAS_PER_BLOCK: 2 ** 19
DATA_GAS_PER_BLOB: 2 ** 17

@jangko jangko added the hard label Jan 11, 2023
@jangko
Copy link
Contributor Author

jangko commented Jan 19, 2023

I think I found an easier solution to implement NetworkTransactionPayload.
Instead of blindly wrap the transaction with network payload, it is much easier to embed the network payload to the transaction.
Therefore we don't need to modify txpool or synchronizer. We only need to focus on rlp + ssz encoding.
We can specialize rlpHash for transaction and produce only txHash for SignedBlobtransaction, without the wrapper.
Additional works is json serialization in rpc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant