2022-03-21 19:43:41 +00:00
|
|
|
package forks
|
|
|
|
|
|
|
|
import (
|
2022-12-13 23:13:49 +00:00
|
|
|
"bytes"
|
2022-03-21 19:43:41 +00:00
|
|
|
"sort"
|
2022-05-13 10:54:45 +00:00
|
|
|
"strings"
|
2022-03-21 19:43:41 +00:00
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
2024-02-15 05:46:47 +00:00
|
|
|
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
|
|
|
"github.com/prysmaticlabs/prysm/v5/config/params"
|
|
|
|
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
|
|
|
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
2022-03-21 19:43:41 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// ForkScheduleEntry is a Version+Epoch tuple for sorted storage in an OrderedSchedule
|
|
|
|
type ForkScheduleEntry struct {
|
|
|
|
Version [fieldparams.VersionLength]byte
|
2023-01-26 14:40:12 +00:00
|
|
|
Epoch primitives.Epoch
|
2022-05-13 10:54:45 +00:00
|
|
|
Name string
|
2022-03-21 19:43:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// OrderedSchedule provides a type that can be used to sort the fork schedule and find the Version
|
2022-05-13 10:54:45 +00:00
|
|
|
// the chain should be at for a given epoch (via VersionForEpoch) or name (via VersionForName).
|
2022-03-21 19:43:41 +00:00
|
|
|
type OrderedSchedule []ForkScheduleEntry
|
|
|
|
|
|
|
|
// Len implements the Len method of sort.Interface
|
|
|
|
func (o OrderedSchedule) Len() int { return len(o) }
|
|
|
|
|
|
|
|
// Swap implements the Swap method of sort.Interface
|
|
|
|
func (o OrderedSchedule) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
|
|
|
|
|
|
|
|
// Less implements the Less method of sort.Interface
|
2022-12-13 23:13:49 +00:00
|
|
|
func (o OrderedSchedule) Less(i, j int) bool {
|
|
|
|
if o[i].Epoch == o[j].Epoch {
|
|
|
|
return bytes.Compare(o[i].Version[:], o[j].Version[:]) < 0
|
|
|
|
}
|
|
|
|
return o[i].Epoch < o[j].Epoch
|
|
|
|
}
|
2022-03-21 19:43:41 +00:00
|
|
|
|
|
|
|
// VersionForEpoch finds the Version with the highest epoch <= the given epoch
|
2023-01-26 14:40:12 +00:00
|
|
|
func (o OrderedSchedule) VersionForEpoch(epoch primitives.Epoch) ([fieldparams.VersionLength]byte, error) {
|
2022-03-21 19:43:41 +00:00
|
|
|
for i := len(o) - 1; i >= 0; i-- {
|
|
|
|
if o[i].Epoch <= epoch {
|
|
|
|
return o[i].Version, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return [fieldparams.VersionLength]byte{}, errors.Wrapf(ErrVersionNotFound, "no epoch in list <= %d", epoch)
|
|
|
|
}
|
|
|
|
|
2022-05-13 10:54:45 +00:00
|
|
|
// VersionForName finds the Version corresponding to the lowercase version of the provided name.
|
|
|
|
func (o OrderedSchedule) VersionForName(name string) ([fieldparams.VersionLength]byte, error) {
|
|
|
|
lower := strings.ToLower(name)
|
|
|
|
for _, e := range o {
|
|
|
|
if e.Name == lower {
|
|
|
|
return e.Version, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return [4]byte{}, errors.Wrapf(ErrVersionNotFound, "no version with name %s", lower)
|
|
|
|
}
|
|
|
|
|
2023-12-07 02:36:25 +00:00
|
|
|
func (o OrderedSchedule) ForkFromVersion(version [fieldparams.VersionLength]byte) (*ethpb.Fork, error) {
|
|
|
|
for i := range o {
|
|
|
|
e := o[i]
|
|
|
|
if e.Version == version {
|
|
|
|
f := ðpb.Fork{Epoch: e.Epoch, CurrentVersion: version[:], PreviousVersion: version[:]}
|
|
|
|
if i > 0 {
|
|
|
|
f.PreviousVersion = o[i-1].Version[:]
|
|
|
|
}
|
|
|
|
return f, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil, errors.Wrapf(ErrVersionNotFound, "could not determine fork for version %#x", version)
|
|
|
|
}
|
|
|
|
|
2022-03-25 17:18:03 +00:00
|
|
|
func (o OrderedSchedule) Previous(version [fieldparams.VersionLength]byte) ([fieldparams.VersionLength]byte, error) {
|
|
|
|
for i := len(o) - 1; i >= 0; i-- {
|
|
|
|
if o[i].Version == version {
|
|
|
|
if i-1 >= 0 {
|
|
|
|
return o[i-1].Version, nil
|
|
|
|
} else {
|
|
|
|
return [fieldparams.VersionLength]byte{}, errors.Wrapf(ErrNoPreviousVersion, "%#x is the first version", version)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return [fieldparams.VersionLength]byte{}, errors.Wrapf(ErrVersionNotFound, "no version in list == %#x", version)
|
|
|
|
}
|
|
|
|
|
2022-05-13 10:54:45 +00:00
|
|
|
// NewOrderedSchedule Converts fork version maps into a list of Version+Epoch+Name values, ordered by Epoch from lowest to highest.
|
2022-03-21 19:43:41 +00:00
|
|
|
// See docs for OrderedSchedule for more detail on what you can do with this type.
|
|
|
|
func NewOrderedSchedule(b *params.BeaconChainConfig) OrderedSchedule {
|
|
|
|
ofs := make(OrderedSchedule, 0)
|
|
|
|
for version, epoch := range b.ForkVersionSchedule {
|
|
|
|
fse := ForkScheduleEntry{
|
|
|
|
Version: version,
|
|
|
|
Epoch: epoch,
|
2022-05-13 10:54:45 +00:00
|
|
|
Name: b.ForkVersionNames[version],
|
2022-03-21 19:43:41 +00:00
|
|
|
}
|
|
|
|
ofs = append(ofs, fse)
|
|
|
|
}
|
|
|
|
sort.Sort(ofs)
|
|
|
|
return ofs
|
|
|
|
}
|