nimbus-eth1/fluffy/tests/test_beacon_chain_block_proof_capella.nim
Kim De Mey 3bb707422b
Rework beacon block proofs to better structure (#2493)
The 3 proofs can be reworked to two proofs as we can use the
BeaconBlock directly instead of BeaconBlockHeader and
BeaconBlockBody. This is possible because the HTR of the
BeaconBlock is the same as the one of the BeaconBlockHeader.

This results in 32 bytes less as an intermediate hash can be
removed. But more importantly looks more clean and compact in
structure and code.
2024-07-17 11:32:05 +02:00

143 lines
4.9 KiB
Nim

# Nimbus
# Copyright (c) 2022-2024 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).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.used.}
{.push raises: [].}
import
unittest2,
beacon_chain/spec/forks,
beacon_chain/spec/datatypes/capella,
beacon_chain /../ tests/testblockutil,
# Mock helpers
beacon_chain /../ tests/mocking/mock_genesis,
../network/history/experimental/beacon_chain_block_proof_capella
# Test suite for the proofs:
# - historicalSummariesProof
# - BeaconBlockProof
# and as last
# - the chain of proofs, BeaconChainBlockProof:
# BlockHash
# -> BeaconBlockProof
# -> historicalSummariesProof
# historical_summaries
#
# Note: The last test makes the others redundant, but keeping them all around
# for now as it might be sufficient to go with just historicalSummariesProof
# (and perhaps BeaconBlockHeaderProof), see comments in beacon_chain_proofs.nim.
#
# TODO:
# - Add more blocks to reach 1+ historical summaries, to make sure that
# indexing is properly tested.
# - Adjust tests to test usage of historical_summaries and historical_roots
# together.
suite "Beacon Chain Block Proofs - Capella":
let
cfg = block:
var res = defaultRuntimeConfig
res.ALTAIR_FORK_EPOCH = GENESIS_EPOCH
res.BELLATRIX_FORK_EPOCH = GENESIS_EPOCH
# res.CAPELLA_FORK_EPOCH = GENESIS_EPOCH
res.CAPELLA_FORK_EPOCH = Epoch(256)
res
state = newClone(initGenesisState(cfg = cfg))
var cache = StateCache()
var blocks: seq[capella.SignedBeaconBlock]
# Note:
# Adding 8192*2 blocks. First block is genesis block and not one of these.
# Then one extra block is needed to get the historical roots, block
# roots and state roots processed.
# index i = 0 is second block.
# index i = 8190 is 8192th block and last one that is part of the first
# historical root
# genesis + 8191 slots, next one will be capella fork
for i in 0 ..< SLOTS_PER_HISTORICAL_ROOT - 1:
discard addTestBlock(state[], cache, cfg = cfg)
# slot 8192 -> 16383
for i in 0 ..< SLOTS_PER_HISTORICAL_ROOT:
blocks.add(addTestBlock(state[], cache, cfg = cfg).capellaData)
# One more slot to hit second SLOTS_PER_HISTORICAL_ROOT, hitting first
# historical_summary.
blocks.add(addTestBlock(state[], cache, cfg = cfg).capellaData)
# Starts from the block after genesis.
const blocksToTest = [
0'u64,
1,
2,
3,
SLOTS_PER_HISTORICAL_ROOT div 2,
SLOTS_PER_HISTORICAL_ROOT - 3,
SLOTS_PER_HISTORICAL_ROOT - 2,
]
test "HistoricalRootsProof for BeaconBlockHeader":
let blockRoots = getStateField(state[], block_roots).data
withState(state[]):
when consensusFork >= ConsensusFork.Capella:
let historical_summaries = forkyState.data.historical_summaries
# for i in 0..<(SLOTS_PER_HISTORICAL_ROOT - 1): # Test all blocks
for i in blocksToTest:
let
beaconBlock = blocks[i].message
historicalRootsIndex = getHistoricalSummariesIndex(beaconBlock.slot, cfg)
blockRootIndex = getBlockRootsIndex(beaconBlock.slot)
let res = buildProof(blockRoots, blockRootIndex)
check res.isOk()
let proof = res.get()
check verifyProof(
blocks[i].root,
proof,
historical_summaries[historicalRootsIndex].block_summary_root,
blockRootIndex,
)
test "BeaconBlockProof for BeaconBlock":
# for i in 0..<(SLOTS_PER_HISTORICAL_ROOT - 1): # Test all blocks
for i in blocksToTest:
let beaconBlock = blocks[i].message
let res = buildProof(beaconBlock)
check res.isOk()
let proof = res.get()
let leave = beaconBlock.body.execution_payload.block_hash
check verifyProof(leave, proof, blocks[i].root)
test "BeaconChainBlockProof for Execution BlockHeader":
let blockRoots = getStateField(state[], block_roots).data
withState(state[]):
when consensusFork >= ConsensusFork.Capella:
let historical_summaries = forkyState.data.historical_summaries
# for i in 0..<(SLOTS_PER_HISTORICAL_ROOT - 1): # Test all blocks
for i in blocksToTest:
let
beaconBlock = blocks[i].message
# Normally we would have an execution BlockHeader that holds this
# value, but we skip the creation of that header for now and just take
# the blockHash from the execution payload.
blockHash = beaconBlock.body.execution_payload.block_hash
let proofRes = buildProof(blockRoots, beaconBlock)
check proofRes.isOk()
let proof = proofRes.get()
check verifyProof(historical_summaries, proof, blockHash, cfg)