@@ -2,61 +2,81 @@ package state
2
2
3
3
import (
4
4
"errors"
5
+ "sort"
5
6
7
+ "github.com/attestantio/go-eth2-client/spec"
6
8
"github.com/attestantio/go-eth2-client/spec/phase0"
7
9
)
8
10
11
+ var (
12
+ // ForkOrder is the canonical order of the forks.
13
+ ForkOrder = []spec.DataVersion {
14
+ spec .DataVersionPhase0 ,
15
+ spec .DataVersionAltair ,
16
+ spec .DataVersionBellatrix ,
17
+ spec .DataVersionCapella ,
18
+ spec .DataVersionDeneb ,
19
+ }
20
+ )
21
+
9
22
// ForkEpoch is a beacon fork that activates at a specific epoch.
10
23
type ForkEpoch struct {
11
- Epoch phase0.Epoch `yaml:"epoch"`
12
- Version string `json:"version"`
13
- Name string `json:"name"`
24
+ Epoch phase0.Epoch `yaml:"epoch"`
25
+ Version string `json:"version"`
26
+ Name spec. DataVersion `json:"name"`
14
27
}
15
28
16
- // Active returns true if the fork is active at the given slot .
17
- func (f * ForkEpoch ) Active (slot , slotsPerEpoch phase0.Slot ) bool {
18
- return phase0 . Epoch ( int ( slot ) / int ( slotsPerEpoch )) >= f .Epoch
29
+ // Active returns true if the fork is active at the given epoch .
30
+ func (f * ForkEpoch ) Active (epoch phase0.Epoch ) bool {
31
+ return epoch >= f .Epoch
19
32
}
20
33
21
34
// ForkEpochs is a list of forks that activate at specific epochs.
22
35
type ForkEpochs []* ForkEpoch
23
36
24
- // Active returns a list of forks that are active at the given slot .
25
- func (f * ForkEpochs ) Active (slot , slotsPerEpoch phase0.Slot ) []* ForkEpoch {
37
+ // Active returns a list of forks that are active at the given epoch .
38
+ func (f * ForkEpochs ) Active (epoch phase0.Epoch ) []* ForkEpoch {
26
39
activated := []* ForkEpoch {}
27
40
28
41
for _ , fork := range * f {
29
- if fork .Active (slot , slotsPerEpoch ) {
42
+ if fork .Active (epoch ) {
30
43
activated = append (activated , fork )
31
44
}
32
45
}
33
46
47
+ // Sort them by our fork order since multiple forks can be activated on the same epoch.
48
+ // For example, a non-phase0 genesis.
49
+ sort .Slice (activated , func (i , j int ) bool {
50
+ return f .IndexOf (activated [i ].Name ) < f .IndexOf (activated [j ].Name )
51
+ })
52
+
34
53
return activated
35
54
}
36
55
37
- // CurrentFork returns the current fork at the given slot .
38
- func (f * ForkEpochs ) Scheduled (slot , slotsPerEpoch phase0.Slot ) []* ForkEpoch {
56
+ // Scheduled returns the scheduled forks at the given epoch .
57
+ func (f * ForkEpochs ) Scheduled (epoch phase0.Epoch ) []* ForkEpoch {
39
58
scheduled := []* ForkEpoch {}
40
59
41
60
for _ , fork := range * f {
42
- if ! fork .Active (slot , slotsPerEpoch ) {
61
+ if ! fork .Active (epoch ) {
43
62
scheduled = append (scheduled , fork )
44
63
}
45
64
}
46
65
47
66
return scheduled
48
67
}
49
68
50
- // CurrentFork returns the current fork at the given slot .
51
- func (f * ForkEpochs ) CurrentFork (slot , slotsPerEpoch phase0.Slot ) (* ForkEpoch , error ) {
69
+ // CurrentFork returns the current fork at the given epoch .
70
+ func (f * ForkEpochs ) CurrentFork (epoch phase0.Epoch ) (* ForkEpoch , error ) {
52
71
found := false
53
72
54
73
largest := & ForkEpoch {
55
74
Epoch : 0 ,
56
75
}
57
76
58
- for _ , fork := range f .Active (slot , slotsPerEpoch ) {
59
- if fork .Active (slot , slotsPerEpoch ) && fork .Epoch >= largest .Epoch {
77
+ active := f .Active (epoch )
78
+ for _ , fork := range active {
79
+ if fork .Epoch >= largest .Epoch {
60
80
found = true
61
81
62
82
largest = fork
@@ -70,13 +90,13 @@ func (f *ForkEpochs) CurrentFork(slot, slotsPerEpoch phase0.Slot) (*ForkEpoch, e
70
90
return largest , nil
71
91
}
72
92
73
- // PreviousFork returns the previous fork at the given slot .
74
- func (f * ForkEpochs ) PreviousFork (slot , slotsPerEpoch phase0.Slot ) (* ForkEpoch , error ) {
93
+ // PreviousFork returns the previous fork at the given epoch .
94
+ func (f * ForkEpochs ) PreviousFork (epoch phase0.Epoch ) (* ForkEpoch , error ) {
75
95
if len (* f ) == 1 {
76
- return f .CurrentFork (slot , slotsPerEpoch )
96
+ return f .CurrentFork (epoch )
77
97
}
78
98
79
- current , err := f .CurrentFork (slot , slotsPerEpoch )
99
+ current , err := f .CurrentFork (epoch )
80
100
if err != nil {
81
101
return nil , err
82
102
}
@@ -87,8 +107,8 @@ func (f *ForkEpochs) PreviousFork(slot, slotsPerEpoch phase0.Slot) (*ForkEpoch,
87
107
Epoch : 0 ,
88
108
}
89
109
90
- for _ , fork := range f .Active (slot , slotsPerEpoch ) {
91
- if fork .Active (slot , slotsPerEpoch ) && fork .Name != current .Name && fork .Epoch > largest .Epoch {
110
+ for _ , fork := range f .Active (epoch ) {
111
+ if fork .Active (epoch ) && fork .Name != current .Name && fork .Epoch > largest .Epoch {
92
112
found = true
93
113
94
114
largest = fork
@@ -105,7 +125,7 @@ func (f *ForkEpochs) PreviousFork(slot, slotsPerEpoch phase0.Slot) (*ForkEpoch,
105
125
// GetByName returns the fork with the given name.
106
126
func (f * ForkEpochs ) GetByName (name string ) (* ForkEpoch , error ) {
107
127
for _ , fork := range * f {
108
- if fork .Name == name {
128
+ if fork .Name . String () == name {
109
129
return fork , nil
110
130
}
111
131
}
@@ -117,3 +137,13 @@ func (f *ForkEpochs) GetByName(name string) (*ForkEpoch, error) {
117
137
func (f * ForkEpochs ) AsScheduledForks () ([]* ScheduledFork , error ) {
118
138
return ForkScheduleFromForkEpochs (* f )
119
139
}
140
+
141
+ // IndexOf returns the index of the given data version in the fork order.
142
+ func (f * ForkEpochs ) IndexOf (name spec.DataVersion ) int {
143
+ for i , version := range ForkOrder {
144
+ if version == name {
145
+ return i
146
+ }
147
+ }
148
+ return - 1 // Return -1 if the name is not found
149
+ }
0 commit comments