mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-02-05 10:35:08 -05:00
Compare commits
2 Commits
develop
...
gloas/fork
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
848a4d56ed | ||
|
|
4340b61a78 |
@@ -31,8 +31,8 @@ func New() *ForkChoice {
|
|||||||
prevJustifiedCheckpoint: &forkchoicetypes.Checkpoint{},
|
prevJustifiedCheckpoint: &forkchoicetypes.Checkpoint{},
|
||||||
finalizedCheckpoint: &forkchoicetypes.Checkpoint{},
|
finalizedCheckpoint: &forkchoicetypes.Checkpoint{},
|
||||||
proposerBoostRoot: [32]byte{},
|
proposerBoostRoot: [32]byte{},
|
||||||
nodeByRoot: make(map[[fieldparams.RootLength]byte]*Node),
|
nodeByRoot: make(map[[fieldparams.RootLength]byte]*PayloadNode),
|
||||||
nodeByPayload: make(map[[fieldparams.RootLength]byte]*Node),
|
nodeByPayload: make(map[[fieldparams.RootLength]byte]*PayloadNode),
|
||||||
slashedIndices: make(map[primitives.ValidatorIndex]bool),
|
slashedIndices: make(map[primitives.ValidatorIndex]bool),
|
||||||
receivedBlocksLastEpoch: [fieldparams.SlotsPerEpoch]primitives.Slot{},
|
receivedBlocksLastEpoch: [fieldparams.SlotsPerEpoch]primitives.Slot{},
|
||||||
}
|
}
|
||||||
@@ -119,14 +119,14 @@ func (f *ForkChoice) InsertNode(ctx context.Context, state state.BeaconState, ro
|
|||||||
return errInvalidNilCheckpoint
|
return errInvalidNilCheckpoint
|
||||||
}
|
}
|
||||||
finalizedEpoch := fc.Epoch
|
finalizedEpoch := fc.Epoch
|
||||||
node, err := f.store.insert(ctx, roblock, justifiedEpoch, finalizedEpoch)
|
pn, err := f.store.insert(ctx, roblock, justifiedEpoch, finalizedEpoch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
jc, fc = f.store.pullTips(state, node, jc, fc)
|
jc, fc = f.store.pullTips(state, pn.node, jc, fc)
|
||||||
if err := f.updateCheckpoints(ctx, jc, fc); err != nil {
|
if err := f.updateCheckpoints(ctx, jc, fc); err != nil {
|
||||||
_, remErr := f.store.removeNode(ctx, node)
|
_, remErr := f.store.removeNode(ctx, pn)
|
||||||
if remErr != nil {
|
if remErr != nil {
|
||||||
log.WithError(remErr).Error("Could not remove node")
|
log.WithError(remErr).Error("Could not remove node")
|
||||||
}
|
}
|
||||||
|
|||||||
32
beacon-chain/forkchoice/doubly-linked-tree/gloas.go
Normal file
32
beacon-chain/forkchoice/doubly-linked-tree/gloas.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package doublylinkedtree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/OffchainLabs/prysm/v7/consensus-types/blocks"
|
||||||
|
"github.com/OffchainLabs/prysm/v7/consensus-types/interfaces"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Store) getNodeInformation(block interfaces.ReadOnlyBeaconBlock, parent *PayloadNode, payloadHash *[32]byte) error {
|
||||||
|
sb, err := block.Body().SignedExecutionPayloadBid()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
wb, err := blocks.WrappedROSignedExecutionPayloadBid(sb)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to wrap signed bid")
|
||||||
|
}
|
||||||
|
bid, err := wb.Bid()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to get bid from wrapped bid")
|
||||||
|
}
|
||||||
|
*payloadHash = bid.BlockHash()
|
||||||
|
if parent == nil {
|
||||||
|
// This is the tree root node.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if bid.ParentBlockHash() == parent.node.payloadHash {
|
||||||
|
//block builds on full
|
||||||
|
parent = s.nodeByPayload[parent.node.payloadHash]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -66,16 +66,27 @@ func (s *Store) head(ctx context.Context) ([32]byte, error) {
|
|||||||
// It then updates the new node's parent with the best child and descendant node.
|
// It then updates the new node's parent with the best child and descendant node.
|
||||||
func (s *Store) insert(ctx context.Context,
|
func (s *Store) insert(ctx context.Context,
|
||||||
roblock consensus_blocks.ROBlock,
|
roblock consensus_blocks.ROBlock,
|
||||||
justifiedEpoch, finalizedEpoch primitives.Epoch) (*Node, error) {
|
justifiedEpoch, finalizedEpoch primitives.Epoch,
|
||||||
|
) (*PayloadNode, error) {
|
||||||
ctx, span := trace.StartSpan(ctx, "doublyLinkedForkchoice.insert")
|
ctx, span := trace.StartSpan(ctx, "doublyLinkedForkchoice.insert")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
root := roblock.Root()
|
root := roblock.Root()
|
||||||
|
// Return if the block has been inserted into Store before.
|
||||||
|
if n, ok := s.nodeByRoot[root]; ok {
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
block := roblock.Block()
|
block := roblock.Block()
|
||||||
slot := block.Slot()
|
slot := block.Slot()
|
||||||
parentRoot := block.ParentRoot()
|
parentRoot := block.ParentRoot()
|
||||||
var payloadHash [32]byte
|
parent := s.nodeByRoot[parentRoot]
|
||||||
if block.Version() >= version.Bellatrix {
|
var payloadHash *[32]byte
|
||||||
|
if block.Version() >= version.Gloas {
|
||||||
|
if err := s.getNodeInformation(block, parent, payloadHash); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else if block.Version() >= version.Bellatrix {
|
||||||
execution, err := block.Body().Execution()
|
execution, err := block.Body().Execution()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -83,12 +94,6 @@ func (s *Store) insert(ctx context.Context,
|
|||||||
copy(payloadHash[:], execution.BlockHash())
|
copy(payloadHash[:], execution.BlockHash())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return if the block has been inserted into Store before.
|
|
||||||
if n, ok := s.nodeByRoot[root]; ok {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
parent := s.nodeByRoot[parentRoot]
|
|
||||||
n := &Node{
|
n := &Node{
|
||||||
slot: slot,
|
slot: slot,
|
||||||
root: root,
|
root: root,
|
||||||
@@ -97,24 +102,39 @@ func (s *Store) insert(ctx context.Context,
|
|||||||
unrealizedJustifiedEpoch: justifiedEpoch,
|
unrealizedJustifiedEpoch: justifiedEpoch,
|
||||||
finalizedEpoch: finalizedEpoch,
|
finalizedEpoch: finalizedEpoch,
|
||||||
unrealizedFinalizedEpoch: finalizedEpoch,
|
unrealizedFinalizedEpoch: finalizedEpoch,
|
||||||
optimistic: true,
|
payloadHash: *payloadHash,
|
||||||
payloadHash: payloadHash,
|
|
||||||
timestamp: time.Now(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the node's target checkpoint
|
// Set the node's target checkpoint
|
||||||
if slot%params.BeaconConfig().SlotsPerEpoch == 0 {
|
if slot%params.BeaconConfig().SlotsPerEpoch == 0 {
|
||||||
n.target = n
|
n.target = n
|
||||||
} else if parent != nil {
|
} else if parent != nil {
|
||||||
if slots.ToEpoch(slot) == slots.ToEpoch(parent.slot) {
|
if slots.ToEpoch(slot) == slots.ToEpoch(parent.node.slot) {
|
||||||
n.target = parent.target
|
n.target = parent.node.target
|
||||||
} else {
|
} else {
|
||||||
n.target = parent
|
n.target = parent.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var ret *PayloadNode
|
||||||
|
// Make the empty node.
|
||||||
|
pn := &PayloadNode{
|
||||||
|
node: n,
|
||||||
|
optimistic: true,
|
||||||
|
timestamp: time.Now(),
|
||||||
|
}
|
||||||
|
s.nodeByRoot[root] = pn
|
||||||
|
ret = pn
|
||||||
|
if block.Version() < version.Gloas {
|
||||||
|
// Make also the full node
|
||||||
|
fn := &PayloadNode{
|
||||||
|
node: n,
|
||||||
|
optimistic: true,
|
||||||
|
timestamp: time.Now(),
|
||||||
|
full: true,
|
||||||
|
}
|
||||||
|
ret = fn
|
||||||
|
s.nodeByPayload[*payloadHash] = fn
|
||||||
|
}
|
||||||
|
|
||||||
s.nodeByPayload[payloadHash] = n
|
|
||||||
s.nodeByRoot[root] = n
|
|
||||||
if parent == nil {
|
if parent == nil {
|
||||||
if s.treeRootNode == nil {
|
if s.treeRootNode == nil {
|
||||||
s.treeRootNode = n
|
s.treeRootNode = n
|
||||||
@@ -122,7 +142,7 @@ func (s *Store) insert(ctx context.Context,
|
|||||||
s.highestReceivedNode = n
|
s.highestReceivedNode = n
|
||||||
} else {
|
} else {
|
||||||
delete(s.nodeByRoot, root)
|
delete(s.nodeByRoot, root)
|
||||||
delete(s.nodeByPayload, payloadHash)
|
delete(s.nodeByPayload, *payloadHash)
|
||||||
return nil, errInvalidParentRoot
|
return nil, errInvalidParentRoot
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -130,7 +150,7 @@ func (s *Store) insert(ctx context.Context,
|
|||||||
// Apply proposer boost
|
// Apply proposer boost
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
if now.Before(s.genesisTime) {
|
if now.Before(s.genesisTime) {
|
||||||
return n, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
currentSlot := slots.CurrentSlot(s.genesisTime)
|
currentSlot := slots.CurrentSlot(s.genesisTime)
|
||||||
sss, err := slots.SinceSlotStart(currentSlot, s.genesisTime, now)
|
sss, err := slots.SinceSlotStart(currentSlot, s.genesisTime, now)
|
||||||
@@ -167,7 +187,7 @@ func (s *Store) insert(ctx context.Context,
|
|||||||
s.highestReceivedNode = n
|
s.highestReceivedNode = n
|
||||||
}
|
}
|
||||||
|
|
||||||
return n, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// pruneFinalizedNodeByRootMap prunes the `nodeByRoot` map
|
// pruneFinalizedNodeByRootMap prunes the `nodeByRoot` map
|
||||||
|
|||||||
@@ -23,22 +23,22 @@ type ForkChoice struct {
|
|||||||
|
|
||||||
// Store defines the fork choice store which includes block nodes and the last view of checkpoint information.
|
// Store defines the fork choice store which includes block nodes and the last view of checkpoint information.
|
||||||
type Store struct {
|
type Store struct {
|
||||||
justifiedCheckpoint *forkchoicetypes.Checkpoint // latest justified epoch in store.
|
justifiedCheckpoint *forkchoicetypes.Checkpoint // latest justified epoch in store.
|
||||||
unrealizedJustifiedCheckpoint *forkchoicetypes.Checkpoint // best unrealized justified checkpoint in store.
|
unrealizedJustifiedCheckpoint *forkchoicetypes.Checkpoint // best unrealized justified checkpoint in store.
|
||||||
unrealizedFinalizedCheckpoint *forkchoicetypes.Checkpoint // best unrealized finalized checkpoint in store.
|
unrealizedFinalizedCheckpoint *forkchoicetypes.Checkpoint // best unrealized finalized checkpoint in store.
|
||||||
prevJustifiedCheckpoint *forkchoicetypes.Checkpoint // previous justified checkpoint in store.
|
prevJustifiedCheckpoint *forkchoicetypes.Checkpoint // previous justified checkpoint in store.
|
||||||
finalizedCheckpoint *forkchoicetypes.Checkpoint // latest finalized epoch in store.
|
finalizedCheckpoint *forkchoicetypes.Checkpoint // latest finalized epoch in store.
|
||||||
proposerBoostRoot [fieldparams.RootLength]byte // latest block root that was boosted after being received in a timely manner.
|
proposerBoostRoot [fieldparams.RootLength]byte // latest block root that was boosted after being received in a timely manner.
|
||||||
previousProposerBoostRoot [fieldparams.RootLength]byte // previous block root that was boosted after being received in a timely manner.
|
previousProposerBoostRoot [fieldparams.RootLength]byte // previous block root that was boosted after being received in a timely manner.
|
||||||
previousProposerBoostScore uint64 // previous proposer boosted root score.
|
previousProposerBoostScore uint64 // previous proposer boosted root score.
|
||||||
finalizedDependentRoot [fieldparams.RootLength]byte // dependent root at finalized checkpoint.
|
finalizedDependentRoot [fieldparams.RootLength]byte // dependent root at finalized checkpoint.
|
||||||
committeeWeight uint64 // tracks the total active validator balance divided by the number of slots per Epoch.
|
committeeWeight uint64 // tracks the total active validator balance divided by the number of slots per Epoch.
|
||||||
treeRootNode *Node // the root node of the store tree.
|
treeRootNode *Node // the root node of the store tree.
|
||||||
headNode *Node // last head Node
|
headNode *Node // last head Node
|
||||||
nodeByRoot map[[fieldparams.RootLength]byte]*Node // nodes indexed by roots.
|
nodeByRoot map[[fieldparams.RootLength]byte]*PayloadNode // nodes indexed by roots.
|
||||||
nodeByPayload map[[fieldparams.RootLength]byte]*Node // nodes indexed by payload Hash
|
nodeByPayload map[[fieldparams.RootLength]byte]*PayloadNode // nodes indexed by payload Hash
|
||||||
slashedIndices map[primitives.ValidatorIndex]bool // the list of equivocating validator indices
|
slashedIndices map[primitives.ValidatorIndex]bool // the list of equivocating validator indices
|
||||||
originRoot [fieldparams.RootLength]byte // The genesis block root
|
originRoot [fieldparams.RootLength]byte // The genesis block root
|
||||||
genesisTime time.Time
|
genesisTime time.Time
|
||||||
highestReceivedNode *Node // The highest slot node.
|
highestReceivedNode *Node // The highest slot node.
|
||||||
receivedBlocksLastEpoch [fieldparams.SlotsPerEpoch]primitives.Slot // Using `highestReceivedSlot`. The slot of blocks received in the last epoch.
|
receivedBlocksLastEpoch [fieldparams.SlotsPerEpoch]primitives.Slot // Using `highestReceivedSlot`. The slot of blocks received in the last epoch.
|
||||||
@@ -51,18 +51,26 @@ type Node struct {
|
|||||||
slot primitives.Slot // slot of the block converted to the node.
|
slot primitives.Slot // slot of the block converted to the node.
|
||||||
root [fieldparams.RootLength]byte // root of the block converted to the node.
|
root [fieldparams.RootLength]byte // root of the block converted to the node.
|
||||||
payloadHash [fieldparams.RootLength]byte // payloadHash of the block converted to the node.
|
payloadHash [fieldparams.RootLength]byte // payloadHash of the block converted to the node.
|
||||||
parent *Node // parent index of this node.
|
parent *PayloadNode // parent index of this node.
|
||||||
target *Node // target checkpoint for
|
target *Node // target checkpoint for
|
||||||
children []*Node // the list of direct children of this Node
|
|
||||||
justifiedEpoch primitives.Epoch // justifiedEpoch of this node.
|
justifiedEpoch primitives.Epoch // justifiedEpoch of this node.
|
||||||
unrealizedJustifiedEpoch primitives.Epoch // the epoch that would be justified if the block would be advanced to the next epoch.
|
unrealizedJustifiedEpoch primitives.Epoch // the epoch that would be justified if the block would be advanced to the next epoch.
|
||||||
finalizedEpoch primitives.Epoch // finalizedEpoch of this node.
|
finalizedEpoch primitives.Epoch // finalizedEpoch of this node.
|
||||||
unrealizedFinalizedEpoch primitives.Epoch // the epoch that would be finalized if the block would be advanced to the next epoch.
|
unrealizedFinalizedEpoch primitives.Epoch // the epoch that would be finalized if the block would be advanced to the next epoch.
|
||||||
balance uint64 // the balance that voted for this node directly
|
balance uint64 // the balance that voted for this node directly
|
||||||
weight uint64 // weight of this node: the total balance including children
|
weight uint64 // weight of this node: the total balance including children
|
||||||
bestDescendant *Node // bestDescendant node of this node.
|
}
|
||||||
optimistic bool // whether the block has been fully validated or not
|
|
||||||
timestamp time.Time // The timestamp when the node was inserted.
|
// PayloadNode defines a full Forkchoice node after the Gloas fork, with the payload status either empty of full
|
||||||
|
type PayloadNode struct {
|
||||||
|
node *Node // the consensus part of this full forkchoice node
|
||||||
|
children []*Node // the list of direct children of this Node
|
||||||
|
bestDescendant *Node // bestDescendant node of this node.
|
||||||
|
full bool // whether this node represents a payload present or not
|
||||||
|
balance uint64 // the balance that voted for this node directly
|
||||||
|
weight uint64 // weight of this node: the total balance including children
|
||||||
|
optimistic bool // whether the block has been fully validated or not
|
||||||
|
timestamp time.Time // The timestamp when the node was inserted.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vote defines an individual validator's vote.
|
// Vote defines an individual validator's vote.
|
||||||
|
|||||||
Reference in New Issue
Block a user