Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions beacon_chain/consensus_object_pools/block_dag.nim
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ type
## Root that can be used to retrieve block data from database

executionBlockHash*: Opt[Eth2Digest]
parentBlockHash*: Opt[Eth2Digest]
## Added in Gloas for computing the `PayloadStatus`
optimisticStatus*: OptimisticStatus

parent*: BlockRef ##\
Expand All @@ -60,12 +62,14 @@ func init*(
T: type BlockRef,
root: Eth2Digest,
executionBlockHash: Opt[Eth2Digest],
parentBlockHash: Opt[Eth2Digest],
optimisticStatus: OptimisticStatus,
slot: Slot,
): BlockRef =
BlockRef(
bid: BlockId(root: root, slot: slot),
executionBlockHash: executionBlockHash,
parentBlockHash: parentBlockHash,
optimisticStatus: optimisticStatus,
)

Expand All @@ -75,7 +79,8 @@ func init*(
phase0.TrustedBeaconBlock | altair.TrustedBeaconBlock): BlockRef =
# Use same formal parameters for simplicity, but it's impossible for these
# blocks to be optimistic.
BlockRef.init(root, Opt.some ZERO_HASH, OptimisticStatus.valid, blck.slot)
BlockRef.init(root, Opt.some ZERO_HASH, Opt.some ZERO_HASH,
OptimisticStatus.valid, blck.slot)

func init*(
T: type BlockRef, root: Eth2Digest, optimisticStatus: OptimisticStatus,
Expand All @@ -85,7 +90,11 @@ func init*(
electra.SomeBeaconBlock | electra.TrustedBeaconBlock |
fulu.SomeBeaconBlock | fulu.TrustedBeaconBlock): BlockRef =
BlockRef.init(
root, Opt.some blck.body.execution_payload.block_hash, optimisticStatus, blck.slot
root,
Opt.some blck.body.execution_payload.block_hash,
Opt.some blck.body.execution_payload.parent_hash,
optimisticStatus,
blck.slot
)

func init*(
Expand All @@ -94,6 +103,7 @@ func init*(
BlockRef.init(
root,
Opt.some blck.body.signed_execution_payload_bid.message.block_hash,
Opt.some blck.body.signed_execution_payload_bid.message.parent_block_hash,
if optimisticStatus == OptimisticStatus.valid or
blck.body.signed_execution_payload_bid.message.block_hash.isZero:
OptimisticStatus.valid
Expand Down Expand Up @@ -179,6 +189,21 @@ func get_ancestor*(

blck = blck.parent

# https://github.com/ethereum/consensus-specs/blob/v1.6.0-beta.1/specs/gloas/fork-choice.md#new-get_parent_payload_status
func get_parent_payload_status*(blck: BlockRef): PayloadStatus =
if isNil(blck.parent) or
# When block_hash is `Opt.none`, it means it requires loading data from
# dag. Returns as PENDING as it is waiting the data to be filled.
blck.parentBlockHash.isNone or
blck.parent.executionBlockHash.isNone:
PAYLOAD_STATUS_PENDING
elif blck.parentBlockHash.value() != blck.parent.executionBlockHash.value() or
# Check either one should be enough to ensure both values are non-zero.
blck.parentBlockHash.value() == ZERO_HASH:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is kind of slow, better to use isZero:

PAYLOAD_STATUS_EMPTY
else:
PAYLOAD_STATUS_FULL

func atSlot*(blck: BlockRef, slot: Slot): BlockSlot =
## Return a BlockSlot at a given slot, with the block set to the closest block
## available. If slot comes from before the block, a suitable block ancestor
Expand Down
36 changes: 28 additions & 8 deletions beacon_chain/consensus_object_pools/blockchain_dag.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1078,12 +1078,14 @@ proc init*(T: type ChainDAGRef, cfg: RuntimeConfig, db: BeaconChainDB,
BlockRef.init(
blck.root,
Opt.none Eth2Digest,
Opt.none Eth2Digest,
OptimisticStatus.notValidated,
blck.summary.slot,
)
else:
BlockRef.init(
blck.root, Opt.some ZERO_HASH, OptimisticStatus.valid, blck.summary.slot
blck.root, Opt.some ZERO_HASH, Opt.some ZERO_HASH,
OptimisticStatus.valid, blck.summary.slot
)

if headRef == nil:
Expand Down Expand Up @@ -2277,26 +2279,37 @@ proc pruneHistory*(dag: ChainDAGRef, startup = false) =
if dag.db.clearBlocks(fork):
break

proc loadExecutionBlockHash*(dag: ChainDAGRef, bid: BlockId): Opt[Eth2Digest] =
proc loadExecutionAndParentBlockHash*(dag: ChainDAGRef, bid: BlockId):
(Opt[Eth2Digest], Opt[Eth2Digest]) =
let blockData = dag.getForkedBlock(bid).valueOr:
# Besides database inconsistency issues, this is hit with checkpoint sync.
# The initial `BlockRef` is created before the checkpoint block is loaded.
# It is backfilled later, so return `none` and keep retrying.
return Opt.none(Eth2Digest)
return (Opt.none(Eth2Digest), Opt.none(Eth2Digest))

withBlck(blockData):
debugGloasComment " "
when consensusFork == ConsensusFork.Gloas:
Opt.some ZERO_HASH
(
Opt.some forkyBlck.message.body.signed_execution_payload_bid.message.block_hash,
Opt.some forkyBlck.message.body.signed_execution_payload_bid.message.parent_block_hash
)
elif consensusFork >= ConsensusFork.Bellatrix:
Opt.some forkyBlck.message.body.execution_payload.block_hash
(
Opt.some forkyBlck.message.body.execution_payload.block_hash,
Opt.some forkyBlck.message.body.execution_payload.parent_hash
)
else:
Opt.some ZERO_HASH
(Opt.some ZERO_HASH, Opt.some ZERO_HASH)

proc loadExecutionBlockHash*(dag: ChainDAGRef, bid: BlockId): Opt[Eth2Digest] =
dag.loadExecutionAndParentBlockHash(bid)[0]

proc loadExecutionBlockHash*(dag: ChainDAGRef, blck: BlockRef): Opt[Eth2Digest] =
if blck.executionBlockHash.isNone:
# Execution block hashes are loaded lazily during startup
blck.executionBlockHash = dag.loadExecutionBlockHash(blck.bid)
let blockHashes = dag.loadExecutionAndParentBlockHash(blck.bid)
blck.executionBlockHash = blockHashes[0]
blck.parentBlockHash = blockHashes[1]

if blck.executionBlockHash == static(Opt.some(ZERO_HASH)):
# The block belongs to Bellatrix+ but the merge has not yet happened
Expand All @@ -2308,6 +2321,13 @@ proc loadExecutionBlockHash*(dag: ChainDAGRef, blck: BlockRef): Opt[Eth2Digest]
cur.executionBlockHash = blck.executionBlockHash
cur = cur.parent

if blck.parentBlockHash == static(Opt.some(ZERO_HASH)):
# Same as executionBlockHash
var cur = blck.parent
while cur != nil and cur.parentBlockHash.isNone:
cur.parentBlockHash = blck.parentBlockHash
cur = cur.parent

blck.executionBlockHash

from std/packedsets import PackedSet, incl, items
Expand Down
Loading