Add historical_roots with proof + test (#1579)
This commit is contained in:
parent
605739ef4c
commit
33fd8b1fae
|
@ -7,10 +7,16 @@
|
||||||
|
|
||||||
#
|
#
|
||||||
# Example of how the beacon state historical_roots field could be provided with
|
# Example of how the beacon state historical_roots field could be provided with
|
||||||
# a Merkle proof that can be verified against the right state root.
|
# a Merkle proof that can be verified against the right beacon state root.
|
||||||
# These historical_roots with their proof could for example be provided over the
|
# These historical_roots with their proof could for example be provided over the
|
||||||
# network and verified on the receivers end.
|
# network and verified on the receivers end.
|
||||||
#
|
#
|
||||||
|
# Note:
|
||||||
|
# Since Capella the historical_roots field is frozen. Thus providing the
|
||||||
|
# historical_roots with a Proof against the latest state seems a bit silly.
|
||||||
|
# One idea could be to embed it into the client just as is done for the
|
||||||
|
# execution header accumulator.
|
||||||
|
#
|
||||||
|
|
||||||
{.push raises: [].}
|
{.push raises: [].}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
# Nimbus
|
||||||
|
# Copyright (c) 2023 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.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Example of how the beacon state historical_summaries field could be provided
|
||||||
|
# with a Merkle proof that can be verified against the right beacon state root.
|
||||||
|
# These historical_summaries with their proof could for example be provided over
|
||||||
|
# the network and verified on the receivers end.
|
||||||
|
#
|
||||||
|
|
||||||
|
{.push raises: [].}
|
||||||
|
|
||||||
|
import
|
||||||
|
stew/results,
|
||||||
|
beacon_chain/spec/forks,
|
||||||
|
beacon_chain/spec/datatypes/capella
|
||||||
|
|
||||||
|
export results
|
||||||
|
|
||||||
|
type
|
||||||
|
HistoricalSummaries* = HashList[HistoricalSummary, Limit HISTORICAL_ROOTS_LIMIT]
|
||||||
|
HistoricalSummariesProof* = array[5, Digest]
|
||||||
|
HistoricalSummariesWithProof* = object
|
||||||
|
historical_summaries: HistoricalSummaries
|
||||||
|
proof: HistoricalSummariesProof
|
||||||
|
|
||||||
|
func buildProof*(
|
||||||
|
state: ForkedHashedBeaconState): Result[HistoricalSummariesProof, string] =
|
||||||
|
let gIndex = GeneralizedIndex(59) # 31 + 28 = 59
|
||||||
|
|
||||||
|
var proof: HistoricalSummariesProof
|
||||||
|
withState(state):
|
||||||
|
? forkyState.data.build_proof(gIndex, proof)
|
||||||
|
|
||||||
|
ok(proof)
|
||||||
|
|
||||||
|
func verifyProof*(
|
||||||
|
historical_summaries: HistoricalSummaries,
|
||||||
|
proof: HistoricalSummariesProof,
|
||||||
|
stateRoot: Digest): bool =
|
||||||
|
let
|
||||||
|
gIndex = GeneralizedIndex(59)
|
||||||
|
leave = hash_tree_root(historical_summaries)
|
||||||
|
|
||||||
|
verify_merkle_multiproof(@[leave], proof, @[gIndex], stateRoot)
|
|
@ -17,4 +17,5 @@ import
|
||||||
./test_content_db,
|
./test_content_db,
|
||||||
./test_discovery_rpc,
|
./test_discovery_rpc,
|
||||||
./test_beacon_chain_block_proof,
|
./test_beacon_chain_block_proof,
|
||||||
./test_beacon_chain_historical_roots
|
./test_beacon_chain_historical_roots,
|
||||||
|
./test_beacon_chain_historical_summaries
|
||||||
|
|
|
@ -13,19 +13,16 @@ import
|
||||||
unittest2,
|
unittest2,
|
||||||
beacon_chain/spec/forks,
|
beacon_chain/spec/forks,
|
||||||
beacon_chain/spec/datatypes/bellatrix,
|
beacon_chain/spec/datatypes/bellatrix,
|
||||||
|
# Test helpers
|
||||||
beacon_chain/../tests/testblockutil,
|
beacon_chain/../tests/testblockutil,
|
||||||
# Mock helpers
|
|
||||||
beacon_chain/../tests/mocking/mock_genesis,
|
beacon_chain/../tests/mocking/mock_genesis,
|
||||||
|
beacon_chain/../tests/consensus_spec/fixtures_utils,
|
||||||
|
|
||||||
../network/history/experimental/beacon_chain_historical_roots
|
../network/history/experimental/beacon_chain_historical_roots
|
||||||
|
|
||||||
suite "Beacon Chain Historical Roots":
|
suite "Beacon Chain Historical Roots":
|
||||||
let
|
let
|
||||||
cfg = block:
|
cfg = genesisTestRuntimeConfig(ConsensusFork.Bellatrix)
|
||||||
var res = defaultRuntimeConfig
|
|
||||||
res.ALTAIR_FORK_EPOCH = GENESIS_EPOCH
|
|
||||||
res.BELLATRIX_FORK_EPOCH = GENESIS_EPOCH
|
|
||||||
res
|
|
||||||
state = newClone(initGenesisState(cfg = cfg))
|
state = newClone(initGenesisState(cfg = cfg))
|
||||||
var cache = StateCache()
|
var cache = StateCache()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
# Nimbus
|
||||||
|
# Copyright (c) 2023 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,
|
||||||
|
# Test helpers
|
||||||
|
beacon_chain/../tests/testblockutil,
|
||||||
|
beacon_chain/../tests/mocking/mock_genesis,
|
||||||
|
beacon_chain/../tests/consensus_spec/fixtures_utils,
|
||||||
|
|
||||||
|
../network/history/experimental/beacon_chain_historical_summaries
|
||||||
|
|
||||||
|
suite "Beacon Chain Historical Summaries":
|
||||||
|
let
|
||||||
|
cfg = genesisTestRuntimeConfig(ConsensusFork.Capella)
|
||||||
|
state = newClone(initGenesisState(cfg = cfg))
|
||||||
|
var cache = StateCache()
|
||||||
|
|
||||||
|
var blocks: seq[capella.SignedBeaconBlock]
|
||||||
|
# Note:
|
||||||
|
# Adding 8192 blocks. First block is genesis block and not one of these.
|
||||||
|
# Then one extra block is needed to get the historical summaries, 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
|
||||||
|
for i in 0..<SLOTS_PER_HISTORICAL_ROOT:
|
||||||
|
blocks.add(addTestBlock(state[], cache, cfg = cfg).capellaData)
|
||||||
|
|
||||||
|
test "Historical Summaries Proof":
|
||||||
|
withState(state[]):
|
||||||
|
when consensusFork >= ConsensusFork.Capella:
|
||||||
|
let historical_summaries = forkyState.data.historical_summaries
|
||||||
|
let res = buildProof(state[])
|
||||||
|
check res.isOk()
|
||||||
|
let proof = res.get()
|
||||||
|
|
||||||
|
withState(state[]):
|
||||||
|
check verifyProof(historical_summaries, proof, forkyState.root)
|
Loading…
Reference in New Issue