nimbus-eth1/fluffy/network/header/header_content.nim

79 lines
2.4 KiB
Nim

# Nimbus
# Copyright (c) 2022 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.
# https://github.com/ethereum/portal-network-specs/blob/master/header-gossip-network.md
{.push raises: [Defect].}
import
nimcrypto/[sha2, hash],
ssz_serialization, ssz_serialization/merkleization,
eth/common/eth_types,
../../common/common_types
export merkleization
const
epochSize = 8192 # blocks
maxHistoricalEpochs = 100_000 # Doesn't really need a limit, does it?
type
# Header Gossip Content Keys
# https://github.com/ethereum/portal-network-specs/blob/master/header-gossip-network.md#content-keys
ContentType* = enum
accumulatorSnapshot = 0x00
newBlockHeader = 0x01
AccumulatorSnapshotKey* = object
accumulatorRootHash*: Bytes32
NewBlockHeaderKey* = object
blockHash*: BlockHash
blockNumber*: UInt256
ContentKey* = object
case contentType*: ContentType
of accumulatorSnapshot:
accumulatorSnapshotKey*: AccumulatorSnapshotKey
of newBlockHeader:
newBlockHeaderKey*: NewBlockHeaderKey
# Header Accumulator
# https://github.com/ethereum/portal-network-specs/blob/master/header-gossip-network.md#accumulator-snapshot
HeaderRecord = object
blockHash: BlockHash
totalDifficulty: UInt256
EpochAccumulator = List[HeaderRecord, epochSize]
Accumulator* = object
historicalEpochs*: List[Bytes32, maxHistoricalEpochs]
currentEpoch*: EpochAccumulator
func updateAccumulator*(a: var Accumulator, header: BlockHeader) =
let lastTotalDifficulty =
if a.currentEpoch.len() == 0:
0.stuint(256)
else:
a.currentEpoch[^1].totalDifficulty
if a.currentEpoch.len() == epochSize:
let epochHash = hash_tree_root(a.currentEpoch)
doAssert(a.historicalEpochs.add(epochHash.data))
a.currentEpoch = EpochAccumulator.init(@[])
let headerRecord =
HeaderRecord(
blockHash: header.blockHash(),
totalDifficulty: lastTotalDifficulty + header.difficulty)
let res = a.currentEpoch.add(headerRecord)
doAssert(res, "Can't fail because of currentEpoch length check")