diff --git a/pysetup/spec_builders/deneb.py b/pysetup/spec_builders/deneb.py index 612ae6cf6..14087702a 100644 --- a/pysetup/spec_builders/deneb.py +++ b/pysetup/spec_builders/deneb.py @@ -28,11 +28,9 @@ def retrieve_blobs_and_proofs(beacon_block_root: Root) -> Tuple[Sequence[Blob], def compute_commitment_inclusion_proof( body: BeaconBlockBody, - blob_kzg_commitments: Sequence[KZGCommitment], - index: int -) -> List[Bytes32, KZG_COMMITMENT_INCLUSION_PROOF_DEPTH]: - # pylint: disable=unused-argument - return [] + index: GeneralizedIndex +) -> Sequence[Bytes32]: + return build_proof(body.get_backing(), index) ''' @classmethod diff --git a/specs/deneb/beacon-chain.md b/specs/deneb/beacon-chain.md index b98ac1259..64bcca5c2 100644 --- a/specs/deneb/beacon-chain.md +++ b/specs/deneb/beacon-chain.md @@ -187,6 +187,19 @@ def kzg_commitment_to_versioned_hash(kzg_commitment: KZGCommitment) -> Versioned return VERSIONED_HASH_VERSION_KZG + hash(kzg_commitment)[1:] ``` +#### `is_valid_merkle_path` + +```python +def is_valid_merkle_path(leaf: Bytes32, branch: Sequence[Bytes32], gindex: int, root: Root) -> bool: + value = leaf + for i in range(len(branch)): + if (gindex >> i) & 1 == 0: + value = hash(branch[i] + value) + else: + value = hash(value + branch[i]) + return value == root +``` + ### Beacon state accessors #### Modified `get_attestation_participation_flag_indices` diff --git a/specs/deneb/p2p-interface.md b/specs/deneb/p2p-interface.md index c7044dc1e..13ac98f64 100644 --- a/specs/deneb/p2p-interface.md +++ b/specs/deneb/p2p-interface.md @@ -51,7 +51,7 @@ The specification of these changes continues in the same format as the network s | `MAX_REQUEST_BLOB_SIDECARS` | `MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK` | Maximum number of blob sidecars in a single request | | `MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS` | `2**12` (= 4096 epochs, ~18 days) | The minimum epoch range over which a node must serve blob sidecars | | `BLOB_SIDECAR_SUBNET_COUNT` | `6` | The number of blob sidecar subnets used in the gossipsub protocol. | -| `BLOB_KZG_COMMITMENTS_GINDEX` | `4 ** 2 + 11` (= 27) | `blob_kzg_commitments` field gindex on `BeaconBlockBody` container | +| `BLOB_KZG_COMMITMENTS_GINDEX` | `get_generalized_index(BeaconBlockBody, 'blob_kzg_commitments')` (= 27) | `blob_kzg_commitments` field gindex on `BeaconBlockBody` container | | `KZG_COMMITMENT_INCLUSION_PROOF_DEPTH` | `floorlog2(BLOB_KZG_COMMITMENTS_GINDEX) + 1 + ceillog2(MAX_BLOB_COMMITMENTS_PER_BLOCK) # noqa: E501` | Merkle proof for `blob_kzg_commitments` list item | ### Containers @@ -86,29 +86,14 @@ class BlobIdentifier(Container): ```python def verify_blob_sidecar_inclusion_proof(blob_sidecar: BlobSidecar) -> bool: - commitment_item_gindex = MAX_BLOB_COMMITMENTS_PER_BLOCK + blob_sidecar.index - gindex = BLOB_KZG_COMMITMENTS_GINDEX + commitment_item_gindex << floorlog2(BLOB_KZG_COMMITMENTS_GINDEX) return is_valid_merkle_path( leaf=blob_sidecar.kzg_commitment.hash_tree_root(), branch=blob_sidecar.commitment_inclusion_proof, - gindex=gindex, + gindex=get_generalized_index(BeaconBlockBody, 'blob_kzg_commitments', blob_sidecar.index), root=blob_sidecar.signed_block_header.message.body_root, ) ``` -#### `is_valid_merkle_path` - -```python -def is_valid_merkle_path(leaf: Bytes32, branch: Sequence[Bytes32], gindex: int, root: Root) -> bool: - value = leaf - for i in range(len(branch)): - if (gindex >> i) & 1 == 0: - value = hash(branch[i] + value) - else: - value = hash(value + branch[i]) - return value == root -``` - ### The gossip domain: gossipsub Some gossip meshes are upgraded in the fork of Deneb to support upgraded types. diff --git a/specs/deneb/validator.md b/specs/deneb/validator.md index 13b816b6f..ba41adf0b 100644 --- a/specs/deneb/validator.md +++ b/specs/deneb/validator.md @@ -165,8 +165,7 @@ def get_blob_sidecars(signed_block: SignedBeaconBlock, kzg_proof=blob_kzg_proofs[index], commitment_inclusion_proof=compute_commitment_inclusion_proof( block.body, - block.body.blob_kzg_commitments[index], - index, + get_generalized_index(BeaconBlockBody, 'blob_kzg_commitments', index), ), signed_block_header=signed_block_header, ) diff --git a/tests/core/pyspec/eth2spec/test/deneb/unittests/validator/test_validator.py b/tests/core/pyspec/eth2spec/test/deneb/unittests/validator/test_validator.py index ef031693d..a45acb071 100644 --- a/tests/core/pyspec/eth2spec/test/deneb/unittests/validator/test_validator.py +++ b/tests/core/pyspec/eth2spec/test/deneb/unittests/validator/test_validator.py @@ -34,7 +34,6 @@ def get_blob_sidecars(spec, signed_block, blobs, blob_kzg_proofs): commitment_inclusion_proof=compute_commitment_inclusion_proof( spec, signed_block.message.body, - signed_block.message.body.blob_kzg_commitments[index], index, ), signed_block_header=signed_block_header, @@ -43,10 +42,9 @@ def get_blob_sidecars(spec, signed_block, blobs, blob_kzg_proofs): ] -def compute_commitment_inclusion_proof(spec, body, kzg_commitment, index): - gindex = (spec.BeaconBlockBody / 'blob_kzg_commitments' / index).gindex() - raise Exception('todo, does remerkleable expose an API to compute proofs?') - return gindex +def compute_commitment_inclusion_proof(spec, body, index): + gindex = spec.get_generalized_index(spec.BeaconBlockBody, 'blob_kzg_commitments', index) + return spec.build_proof(body, gindex) @with_deneb_and_later