You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We need to implement and benchmark a simple version of Latest Message Driven (LMD) GHOST (Greediest Heaviest Observed Sub-Tree) as a fork-choice algorithm for the beacon chain. As defined in the latest specification:
Spec Definition
The beacon chain fork choice rule is a hybrid that combines justification and finality with Latest Message Driven (LMD) Greediest Heaviest Observed SubTree (GHOST). At any point in time a validator v subjectively calculates the beacon chain head as follows.
Let store be the set of attestations and blocks that the validatorv has observed and verified (in particular, block ancestors must be recursively verified). Attestations not part of any chain are still included in store.
Let finalized_head be the finalized block with the highest slot number. (A block B is finalized if there is a descendant of B in store the processing of which sets B as finalized.)
Let justified_head be the descendant of finalized_head with the highest slot number that has been justified for at least EPOCH_LENGTH slots. (A block B is justified if there is a descendant of B in store the processing of which sets B as justified.) If no such descendant exists set justified_head to finalized_head.
Let get_ancestor(store, block, slot) be the ancestor of block with slot number slot. The get_ancestor function can be defined recursively as def get_ancestor(store, block, slot): return block if block.slot == slot else get_ancestor(store, store.get_parent(block), slot).
Let get_latest_attestation(store, validator) be the attestation with the highest slot number in store from validator. If several such attestations exist, use the one the validatorv observed first.
Let get_latest_attestation_target(store, validator) be the target block in the attestation get_latest_attestation(store, validator).
The head is lmd_ghost(store, justified_head) where the function lmd_ghost is defined below. Note that the implementation below is suboptimal; there are implementations that compute the head in time logarithmic in slot count.
Though the above is not the only way to do it. Another possible approach is an "online" algorithm where you keep extra data that lets you compute an upper bound on how many blocks back you would have to recalculate (basically, at each height store the total deposits supporting that block minus the total deposits supporting its best competitor, and then decrease that value every time there are validator balance changes or a validator switches from supporting that chain to not supporting that chain, and recompute from that height when the value reaches zero). There's a large space of LMD GHOST optimizations that hasn't really been explored yet.
Hi all,
We need to implement and benchmark a simple version of Latest Message Driven (LMD) GHOST (Greediest Heaviest Observed Sub-Tree) as a fork-choice algorithm for the beacon chain. As defined in the latest specification:
Spec Definition
The beacon chain fork choice rule is a hybrid that combines justification and finality with Latest Message Driven (LMD) Greediest Heaviest Observed SubTree (GHOST). At any point in time a validator v subjectively calculates the beacon chain head as follows.
store
be the set of attestations and blocks that the validatorv
has observed and verified (in particular, block ancestors must be recursively verified). Attestations not part of any chain are still included instore
.finalized_head
be the finalized block with the highest slot number. (A blockB
is finalized if there is a descendant ofB
instore
the processing of which setsB
as finalized.)justified_head
be the descendant offinalized_head
with the highest slot number that has been justified for at leastEPOCH_LENGTH
slots. (A blockB
is justified if there is a descendant ofB
instore
the processing of which setsB
as justified.) If no such descendant exists setjustified_head
tofinalized_head
.get_ancestor(store, block, slot)
be the ancestor ofblock
with slot numberslot
. Theget_ancestor
function can be defined recursively asdef get_ancestor(store, block, slot): return block if block.slot == slot else get_ancestor(store, store.get_parent(block), slot)
.get_latest_attestation(store, validator)
be the attestation with the highest slot number instore
fromvalidator
. If several such attestations exist, use the one the validatorv
observed first.get_latest_attestation_target(store, validator)
be the target block in the attestationget_latest_attestation(store, validator)
.lmd_ghost(store, justified_head)
where the functionlmd_ghost
is defined below. Note that the implementation below is suboptimal; there are implementations that compute the head in time logarithmic in slot count.The text was updated successfully, but these errors were encountered: