-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement EIP7805: Fork-choice enforced Inclusion Lists
- Loading branch information
1 parent
6ce6b86
commit 23b7573
Showing
81 changed files
with
3,646 additions
and
1,644 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package blockchain | ||
|
||
import ( | ||
"context" | ||
"time" | ||
|
||
"github.com/prysmaticlabs/prysm/v5/config/params" | ||
"github.com/prysmaticlabs/prysm/v5/time/slots" | ||
) | ||
|
||
const updateInclusionListBlockInterval = time.Second | ||
|
||
// Routine that updates block building with inclusion lists one second before the slot starts. | ||
func (s *Service) updateBlockWithInclusionListRoutine() { | ||
if err := s.waitForSync(); err != nil { | ||
log.WithError(err).Error("Failed to wait for initial sync") | ||
return | ||
} | ||
|
||
interval := time.Second*time.Duration(params.BeaconConfig().SecondsPerSlot) - updateInclusionListBlockInterval | ||
ticker := slots.NewSlotTickerWithIntervals(s.genesisTime, []time.Duration{interval}) | ||
|
||
for { | ||
select { | ||
case <-s.ctx.Done(): | ||
return | ||
case <-ticker.C(): | ||
s.updateBlockWithInclusionList(context.Background()) | ||
} | ||
} | ||
} | ||
|
||
// Updates block building with inclusion lists, the current payload ID, and the new upload ID. | ||
func (s *Service) updateBlockWithInclusionList(ctx context.Context) { | ||
currentSlot := s.CurrentSlot() | ||
|
||
// Skip update if not in or past the FOCIL fork epoch. | ||
if slots.ToEpoch(currentSlot) < params.BeaconConfig().FocilForkEpoch { | ||
return | ||
} | ||
|
||
s.cfg.ForkChoiceStore.RLock() | ||
defer s.cfg.ForkChoiceStore.RUnlock() | ||
|
||
headRoot := s.headRoot() | ||
id, found := s.cfg.PayloadIDCache.PayloadID(currentSlot+1, headRoot) | ||
if !found { | ||
return | ||
} | ||
|
||
txs := s.inclusionListCache.Get(currentSlot) | ||
newID, err := s.cfg.ExecutionEngineCaller.UpdatePayloadWithInclusionList(ctx, id, txs) | ||
if err != nil { | ||
log.WithError(err).Error("Failed to update block with inclusion list") | ||
return | ||
} | ||
|
||
s.cfg.PayloadIDCache.Set(currentSlot+1, headRoot, *newID) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package cache | ||
|
||
import ( | ||
"crypto/sha256" | ||
"sync" | ||
|
||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" | ||
) | ||
|
||
type InclusionLists struct { | ||
mu sync.RWMutex | ||
ils map[primitives.Slot]map[primitives.ValidatorIndex]struct { | ||
txs [][]byte | ||
seenTwice bool | ||
} | ||
} | ||
|
||
// NewInclusionLists initializes a new InclusionLists instance. | ||
func NewInclusionLists() *InclusionLists { | ||
return &InclusionLists{ | ||
ils: make(map[primitives.Slot]map[primitives.ValidatorIndex]struct { | ||
txs [][]byte | ||
seenTwice bool | ||
}), | ||
} | ||
} | ||
|
||
// Add adds a set of transactions for a specific slot and validator index. | ||
func (i *InclusionLists) Add(slot primitives.Slot, validatorIndex primitives.ValidatorIndex, txs [][]byte) { | ||
i.mu.Lock() | ||
defer i.mu.Unlock() | ||
|
||
if _, ok := i.ils[slot]; !ok { | ||
i.ils[slot] = make(map[primitives.ValidatorIndex]struct { | ||
txs [][]byte | ||
seenTwice bool | ||
}) | ||
} | ||
|
||
entry := i.ils[slot][validatorIndex] | ||
if entry.seenTwice { | ||
return // No need to modify if already marked as seen twice. | ||
} | ||
|
||
if entry.txs == nil { | ||
entry.txs = txs | ||
} else { | ||
entry.seenTwice = true | ||
entry.txs = nil // Clear transactions to save space if seen twice. | ||
} | ||
i.ils[slot][validatorIndex] = entry | ||
} | ||
|
||
// Get retrieves unique transactions for a specific slot. | ||
func (i *InclusionLists) Get(slot primitives.Slot) [][]byte { | ||
i.mu.RLock() | ||
defer i.mu.RUnlock() | ||
|
||
ils, exists := i.ils[slot] | ||
if !exists { | ||
return nil | ||
} | ||
|
||
var uniqueTxs [][]byte | ||
seen := make(map[[32]byte]struct{}) | ||
for _, entry := range ils { | ||
for _, tx := range entry.txs { | ||
hash := sha256.Sum256(tx) | ||
if _, duplicate := seen[hash]; !duplicate { | ||
uniqueTxs = append(uniqueTxs, tx) | ||
seen[hash] = struct{}{} | ||
} | ||
} | ||
} | ||
return uniqueTxs | ||
} | ||
|
||
// Delete removes all inclusion lists for a specific slot. | ||
func (i *InclusionLists) Delete(slot primitives.Slot) { | ||
i.mu.Lock() | ||
defer i.mu.Unlock() | ||
|
||
delete(i.ils, slot) | ||
} | ||
|
||
// SeenTwice checks if a validator's transactions were marked as seen twice for a specific slot. | ||
func (i *InclusionLists) SeenTwice(slot primitives.Slot, idx primitives.ValidatorIndex) bool { | ||
i.mu.RLock() | ||
defer i.mu.RUnlock() | ||
|
||
ils, exists := i.ils[slot] | ||
if !exists { | ||
return false | ||
} | ||
|
||
entry, exists := ils[idx] | ||
return exists && entry.seenTwice | ||
} |
Oops, something went wrong.