From a94ba8cbb5fe068ea3310c007728aad45b7d5d84 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Fri, 10 Jan 2025 23:55:42 +0100 Subject: [PATCH] Add test to compare SSZ bounds against Teku impl (#6836) * Add test to compare SSZ bounds against Teku impl Ensure that our SSZ bounds are computed the same way as in Teku by comparing the bounds for `deneb.SignedBeaconBlock`. * Lint * Make platform agnostic regarding how Git checks out newlines --- AllTests-mainnet.md | 7 +- tests/test_eth2_ssz_serialization.nim | 65 +++++++- ...SszLengthBounds_SignedBeaconBlockDeneb.txt | 149 ++++++++++++++++++ 3 files changed, 217 insertions(+), 4 deletions(-) create mode 100644 tests/test_files/SszLengthBounds_SignedBeaconBlockDeneb.txt diff --git a/AllTests-mainnet.md b/AllTests-mainnet.md index 0520a2382c..76753732d2 100644 --- a/AllTests-mainnet.md +++ b/AllTests-mainnet.md @@ -875,6 +875,11 @@ OK: 2/2 Fail: 0/2 Skip: 0/2 + Accelerated shuffling computation (with epochRefState jump) OK ``` OK: 2/2 Fail: 0/2 Skip: 0/2 +## Size bounds +```diff ++ SignedBeaconBlockDeneb OK +``` +OK: 1/1 Fail: 0/1 Skip: 0/1 ## Slashing Interchange tests [Preset: mainnet] ```diff + Slashing test: duplicate_pubkey_not_slashable.json OK @@ -1144,4 +1149,4 @@ OK: 2/2 Fail: 0/2 Skip: 0/2 OK: 9/9 Fail: 0/9 Skip: 0/9 ---TOTAL--- -OK: 777/782 Fail: 0/782 Skip: 5/782 +OK: 778/783 Fail: 0/783 Skip: 5/783 diff --git a/tests/test_eth2_ssz_serialization.nim b/tests/test_eth2_ssz_serialization.nim index f782b68590..682f3e2a0b 100644 --- a/tests/test_eth2_ssz_serialization.nim +++ b/tests/test_eth2_ssz_serialization.nim @@ -1,5 +1,5 @@ # beacon_chain -# Copyright (c) 2018-2024 Status Research & Development GmbH +# Copyright (c) 2018-2025 Status Research & Development GmbH # Licensed and distributed under either of # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). @@ -9,9 +9,11 @@ {.used.} import + std/strutils, unittest2, - ../beacon_chain/spec/datatypes/[phase0, altair], - ../beacon_chain/spec/eth2_ssz_serialization + ../beacon_chain/spec/datatypes/[phase0, altair, bellatrix, deneb], + ../beacon_chain/spec/eth2_ssz_serialization, + ./consensus_spec/os_ops static: doAssert isFixedSize(Slot) == true @@ -49,3 +51,60 @@ suite "Specific field types": testit(phase0.TrustedSignedBeaconBlock) testit(altair.SignedBeaconBlock) testit(altair.TrustedSignedBeaconBlock) + +suite "Size bounds": + test "SignedBeaconBlockDeneb": + # https://gist.github.com/tbenr/a0ae19fe7496106886ec1f3cc097c208 + template sourceDir: string = currentSourcePath.rsplit(DirSep, 1)[0] + let expected = os_ops.readFile( + sourceDir/"test_files"/"SszLengthBounds_SignedBeaconBlockDeneb.txt") + + var + res = "" + loc = @["SignedBeaconBlockDeneb"] + func record(T: typedesc) = + when T is SomeSig|ValidatorPubKey: + res.add loc.join(".") & "[" & $T.blob.len & "]: SszLengthBounds" & + "{min=" & $T.minSize & ", max=" & $T.maxSize & "}\n" + loc[^1].add "[element]" + byte.record() + elif T is ExecutionAddress|BloomLogs: + res.add loc.join(".") & "[" & $T.data.len & "]: SszLengthBounds" & + "{min=" & $T.minSize & ", max=" & $T.maxSize & "}\n" + loc[^1].add "[element]" + byte.record() + elif T is KzgCommitment: + res.add loc.join(".") & "[" & $T.bytes.len & "]: SszLengthBounds" & + "{min=" & $T.minSize & ", max=" & $T.maxSize & "}\n" + loc[^1].add "[element]" + byte.record() + elif T is array|HashArray: + res.add loc.join(".") & "[" & $T.len & "]: SszLengthBounds" & + "{min=" & $T.minSize & ", max=" & $T.maxSize & "}\n" + loc[^1].add "[element]" + ElemType(T).record() + elif T is List|HashList: + res.add loc.join(".") & "(" & $T.maxLen & "): SszLengthBounds" & + "{min=" & $T.minSize & ", max=" & $T.maxSize & "}\n" + loc[^1].add "(element)" + ElemType(T).record() + elif T is BitArray: + res.add loc.join(".") & "[" & $T.bits & "]: SszLengthBounds" & + "{min=" & $T.minSize & ", max=" & $T.maxSize & "}\n" + res.add loc.join(".") & "[element]: SszLengthBounds" & + "{min=0(+1 bits), max=0(+1 bits)}\n" + elif T is BitList: + res.add loc.join(".") & "(" & $T.maxLen & "): SszLengthBounds" & + "{min=" & $T.minSize & ", max=" & $T.maxSize & "}\n" + res.add loc.join(".") & "(element): SszLengthBounds" & + "{min=0(+1 bits), max=0(+1 bits)}\n" + else: + res.add loc.join(".") & ": SszLengthBounds" & + "{min=" & $T.minSize & ", max=" & $T.maxSize & "}\n" + when T is object and T isnot Eth2Digest|UInt256: + T.enumAllSerializedFields(): + loc.add fieldName + record(FieldType) + discard loc.pop() + record deneb.SignedBeaconBlock + check res.splitLines() == expected.splitLines() diff --git a/tests/test_files/SszLengthBounds_SignedBeaconBlockDeneb.txt b/tests/test_files/SszLengthBounds_SignedBeaconBlockDeneb.txt new file mode 100644 index 0000000000..d3eb6414d1 --- /dev/null +++ b/tests/test_files/SszLengthBounds_SignedBeaconBlockDeneb.txt @@ -0,0 +1,149 @@ +SignedBeaconBlockDeneb: SszLengthBounds{min=1104, max=1125899911395480} +SignedBeaconBlockDeneb.message: SszLengthBounds{min=1004, max=1125899911395380} +SignedBeaconBlockDeneb.message.slot: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.proposer_index: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.parent_root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.state_root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body: SszLengthBounds{min=920, max=1125899911395296} +SignedBeaconBlockDeneb.message.body.randao_reveal[96]: SszLengthBounds{min=96, max=96} +SignedBeaconBlockDeneb.message.body.randao_reveal[element]: SszLengthBounds{min=1, max=1} +SignedBeaconBlockDeneb.message.body.eth1_data: SszLengthBounds{min=72, max=72} +SignedBeaconBlockDeneb.message.body.eth1_data.deposit_root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.eth1_data.deposit_count: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.eth1_data.block_hash: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.graffiti: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.proposer_slashings(16): SszLengthBounds{min=0, max=6656} +SignedBeaconBlockDeneb.message.body.proposer_slashings(element): SszLengthBounds{min=416, max=416} +SignedBeaconBlockDeneb.message.body.proposer_slashings(element).signed_header_1: SszLengthBounds{min=208, max=208} +SignedBeaconBlockDeneb.message.body.proposer_slashings(element).signed_header_1.message: SszLengthBounds{min=112, max=112} +SignedBeaconBlockDeneb.message.body.proposer_slashings(element).signed_header_1.message.slot: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.proposer_slashings(element).signed_header_1.message.proposer_index: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.proposer_slashings(element).signed_header_1.message.parent_root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.proposer_slashings(element).signed_header_1.message.state_root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.proposer_slashings(element).signed_header_1.message.body_root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.proposer_slashings(element).signed_header_1.signature[96]: SszLengthBounds{min=96, max=96} +SignedBeaconBlockDeneb.message.body.proposer_slashings(element).signed_header_1.signature[element]: SszLengthBounds{min=1, max=1} +SignedBeaconBlockDeneb.message.body.proposer_slashings(element).signed_header_2: SszLengthBounds{min=208, max=208} +SignedBeaconBlockDeneb.message.body.proposer_slashings(element).signed_header_2.message: SszLengthBounds{min=112, max=112} +SignedBeaconBlockDeneb.message.body.proposer_slashings(element).signed_header_2.message.slot: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.proposer_slashings(element).signed_header_2.message.proposer_index: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.proposer_slashings(element).signed_header_2.message.parent_root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.proposer_slashings(element).signed_header_2.message.state_root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.proposer_slashings(element).signed_header_2.message.body_root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.proposer_slashings(element).signed_header_2.signature[96]: SszLengthBounds{min=96, max=96} +SignedBeaconBlockDeneb.message.body.proposer_slashings(element).signed_header_2.signature[element]: SszLengthBounds{min=1, max=1} +SignedBeaconBlockDeneb.message.body.attester_slashings(2): SszLengthBounds{min=0, max=66472} +SignedBeaconBlockDeneb.message.body.attester_slashings(element): SszLengthBounds{min=464, max=33232} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_1: SszLengthBounds{min=228, max=16612} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_1.attesting_indices(2048): SszLengthBounds{min=0, max=16384} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_1.attesting_indices(element): SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_1.data: SszLengthBounds{min=128, max=128} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_1.data.slot: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_1.data.index: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_1.data.beacon_block_root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_1.data.source: SszLengthBounds{min=40, max=40} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_1.data.source.epoch: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_1.data.source.root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_1.data.target: SszLengthBounds{min=40, max=40} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_1.data.target.epoch: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_1.data.target.root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_1.signature[96]: SszLengthBounds{min=96, max=96} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_1.signature[element]: SszLengthBounds{min=1, max=1} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_2: SszLengthBounds{min=228, max=16612} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_2.attesting_indices(2048): SszLengthBounds{min=0, max=16384} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_2.attesting_indices(element): SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_2.data: SszLengthBounds{min=128, max=128} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_2.data.slot: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_2.data.index: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_2.data.beacon_block_root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_2.data.source: SszLengthBounds{min=40, max=40} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_2.data.source.epoch: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_2.data.source.root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_2.data.target: SszLengthBounds{min=40, max=40} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_2.data.target.epoch: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_2.data.target.root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_2.signature[96]: SszLengthBounds{min=96, max=96} +SignedBeaconBlockDeneb.message.body.attester_slashings(element).attestation_2.signature[element]: SszLengthBounds{min=1, max=1} +SignedBeaconBlockDeneb.message.body.attestations(128): SszLengthBounds{min=0, max=62592} +SignedBeaconBlockDeneb.message.body.attestations(element): SszLengthBounds{min=229, max=485} +SignedBeaconBlockDeneb.message.body.attestations(element).aggregation_bits(2048): SszLengthBounds{min=1, max=257} +SignedBeaconBlockDeneb.message.body.attestations(element).aggregation_bits(element): SszLengthBounds{min=0(+1 bits), max=0(+1 bits)} +SignedBeaconBlockDeneb.message.body.attestations(element).data: SszLengthBounds{min=128, max=128} +SignedBeaconBlockDeneb.message.body.attestations(element).data.slot: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.attestations(element).data.index: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.attestations(element).data.beacon_block_root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.attestations(element).data.source: SszLengthBounds{min=40, max=40} +SignedBeaconBlockDeneb.message.body.attestations(element).data.source.epoch: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.attestations(element).data.source.root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.attestations(element).data.target: SszLengthBounds{min=40, max=40} +SignedBeaconBlockDeneb.message.body.attestations(element).data.target.epoch: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.attestations(element).data.target.root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.attestations(element).signature[96]: SszLengthBounds{min=96, max=96} +SignedBeaconBlockDeneb.message.body.attestations(element).signature[element]: SszLengthBounds{min=1, max=1} +SignedBeaconBlockDeneb.message.body.deposits(16): SszLengthBounds{min=0, max=19840} +SignedBeaconBlockDeneb.message.body.deposits(element): SszLengthBounds{min=1240, max=1240} +SignedBeaconBlockDeneb.message.body.deposits(element).proof[33]: SszLengthBounds{min=1056, max=1056} +SignedBeaconBlockDeneb.message.body.deposits(element).proof[element]: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.deposits(element).data: SszLengthBounds{min=184, max=184} +SignedBeaconBlockDeneb.message.body.deposits(element).data.pubkey[48]: SszLengthBounds{min=48, max=48} +SignedBeaconBlockDeneb.message.body.deposits(element).data.pubkey[element]: SszLengthBounds{min=1, max=1} +SignedBeaconBlockDeneb.message.body.deposits(element).data.withdrawal_credentials: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.deposits(element).data.amount: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.deposits(element).data.signature[96]: SszLengthBounds{min=96, max=96} +SignedBeaconBlockDeneb.message.body.deposits(element).data.signature[element]: SszLengthBounds{min=1, max=1} +SignedBeaconBlockDeneb.message.body.voluntary_exits(16): SszLengthBounds{min=0, max=1792} +SignedBeaconBlockDeneb.message.body.voluntary_exits(element): SszLengthBounds{min=112, max=112} +SignedBeaconBlockDeneb.message.body.voluntary_exits(element).message: SszLengthBounds{min=16, max=16} +SignedBeaconBlockDeneb.message.body.voluntary_exits(element).message.epoch: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.voluntary_exits(element).message.validator_index: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.voluntary_exits(element).signature[96]: SszLengthBounds{min=96, max=96} +SignedBeaconBlockDeneb.message.body.voluntary_exits(element).signature[element]: SszLengthBounds{min=1, max=1} +SignedBeaconBlockDeneb.message.body.sync_aggregate: SszLengthBounds{min=160, max=160} +SignedBeaconBlockDeneb.message.body.sync_aggregate.sync_committee_bits[512]: SszLengthBounds{min=64, max=64} +SignedBeaconBlockDeneb.message.body.sync_aggregate.sync_committee_bits[element]: SszLengthBounds{min=0(+1 bits), max=0(+1 bits)} +SignedBeaconBlockDeneb.message.body.sync_aggregate.sync_committee_signature[96]: SszLengthBounds{min=96, max=96} +SignedBeaconBlockDeneb.message.body.sync_aggregate.sync_committee_signature[element]: SszLengthBounds{min=1, max=1} +SignedBeaconBlockDeneb.message.body.execution_payload: SszLengthBounds{min=528, max=1125899911038192} +SignedBeaconBlockDeneb.message.body.execution_payload.parent_hash: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.execution_payload.fee_recipient[20]: SszLengthBounds{min=20, max=20} +SignedBeaconBlockDeneb.message.body.execution_payload.fee_recipient[element]: SszLengthBounds{min=1, max=1} +SignedBeaconBlockDeneb.message.body.execution_payload.state_root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.execution_payload.receipts_root: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.execution_payload.logs_bloom[256]: SszLengthBounds{min=256, max=256} +SignedBeaconBlockDeneb.message.body.execution_payload.logs_bloom[element]: SszLengthBounds{min=1, max=1} +SignedBeaconBlockDeneb.message.body.execution_payload.prev_randao: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.execution_payload.block_number: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.execution_payload.gas_limit: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.execution_payload.gas_used: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.execution_payload.timestamp: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.execution_payload.extra_data(32): SszLengthBounds{min=0, max=32} +SignedBeaconBlockDeneb.message.body.execution_payload.extra_data(element): SszLengthBounds{min=1, max=1} +SignedBeaconBlockDeneb.message.body.execution_payload.base_fee_per_gas: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.execution_payload.block_hash: SszLengthBounds{min=32, max=32} +SignedBeaconBlockDeneb.message.body.execution_payload.transactions(1048576): SszLengthBounds{min=0, max=1125899911036928} +SignedBeaconBlockDeneb.message.body.execution_payload.transactions(element)(1073741824): SszLengthBounds{min=0, max=1073741824} +SignedBeaconBlockDeneb.message.body.execution_payload.transactions(element)(element): SszLengthBounds{min=1, max=1} +SignedBeaconBlockDeneb.message.body.execution_payload.withdrawals(16): SszLengthBounds{min=0, max=704} +SignedBeaconBlockDeneb.message.body.execution_payload.withdrawals(element): SszLengthBounds{min=44, max=44} +SignedBeaconBlockDeneb.message.body.execution_payload.withdrawals(element).index: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.execution_payload.withdrawals(element).validator_index: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.execution_payload.withdrawals(element).address[20]: SszLengthBounds{min=20, max=20} +SignedBeaconBlockDeneb.message.body.execution_payload.withdrawals(element).address[element]: SszLengthBounds{min=1, max=1} +SignedBeaconBlockDeneb.message.body.execution_payload.withdrawals(element).amount: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.execution_payload.blob_gas_used: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.execution_payload.excess_blob_gas: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.bls_to_execution_changes(16): SszLengthBounds{min=0, max=2752} +SignedBeaconBlockDeneb.message.body.bls_to_execution_changes(element): SszLengthBounds{min=172, max=172} +SignedBeaconBlockDeneb.message.body.bls_to_execution_changes(element).message: SszLengthBounds{min=76, max=76} +SignedBeaconBlockDeneb.message.body.bls_to_execution_changes(element).message.validator_index: SszLengthBounds{min=8, max=8} +SignedBeaconBlockDeneb.message.body.bls_to_execution_changes(element).message.from_bls_pubkey[48]: SszLengthBounds{min=48, max=48} +SignedBeaconBlockDeneb.message.body.bls_to_execution_changes(element).message.from_bls_pubkey[element]: SszLengthBounds{min=1, max=1} +SignedBeaconBlockDeneb.message.body.bls_to_execution_changes(element).message.to_execution_address[20]: SszLengthBounds{min=20, max=20} +SignedBeaconBlockDeneb.message.body.bls_to_execution_changes(element).message.to_execution_address[element]: SszLengthBounds{min=1, max=1} +SignedBeaconBlockDeneb.message.body.bls_to_execution_changes(element).signature[96]: SszLengthBounds{min=96, max=96} +SignedBeaconBlockDeneb.message.body.bls_to_execution_changes(element).signature[element]: SszLengthBounds{min=1, max=1} +SignedBeaconBlockDeneb.message.body.blob_kzg_commitments(4096): SszLengthBounds{min=0, max=196608} +SignedBeaconBlockDeneb.message.body.blob_kzg_commitments(element)[48]: SszLengthBounds{min=48, max=48} +SignedBeaconBlockDeneb.message.body.blob_kzg_commitments(element)[element]: SszLengthBounds{min=1, max=1} +SignedBeaconBlockDeneb.signature[96]: SszLengthBounds{min=96, max=96} +SignedBeaconBlockDeneb.signature[element]: SszLengthBounds{min=1, max=1}