@@ -25,7 +25,9 @@ type Schedule []BeaconPoint
25
25
func (bs Schedule ) BeaconForEpoch (e abi.ChainEpoch ) RandomBeacon {
26
26
for i := len (bs ) - 1 ; i >= 0 ; i -- {
27
27
bp := bs [i ]
28
- if e >= bp .Start {
28
+ // The new network version kicks in at one _after_ the upgrade height itself,
29
+ // so we switch to the new beacon when _strictly_ greater than bp.Start
30
+ if e > bp .Start {
29
31
return bp .Beacon
30
32
}
31
33
}
@@ -43,31 +45,31 @@ type BeaconPoint struct {
43
45
// been posted on chain.
44
46
type RandomBeacon interface {
45
47
Entry (context.Context , uint64 ) <- chan Response
46
- VerifyEntry (types.BeaconEntry , types. BeaconEntry ) error
48
+ VerifyEntry (entry types.BeaconEntry , prevEntrySig [] byte ) error
47
49
MaxBeaconRoundForEpoch (network.Version , abi.ChainEpoch ) uint64
48
50
}
49
51
50
52
func ValidateBlockValues (bSchedule Schedule , nv network.Version , h * types.BlockHeader , parentEpoch abi.ChainEpoch ,
51
53
prevEntry types.BeaconEntry ) error {
52
- {
53
- parentBeacon := bSchedule .BeaconForEpoch (parentEpoch )
54
- currBeacon := bSchedule .BeaconForEpoch (h .Height )
55
- if parentBeacon != currBeacon {
56
- if len (h .BeaconEntries ) != 2 {
57
- return xerrors .Errorf ("expected two beacon entries at beacon fork, got %d" , len (h .BeaconEntries ))
58
- }
59
- err := currBeacon .VerifyEntry (h .BeaconEntries [1 ], h .BeaconEntries [0 ])
60
- if err != nil {
61
- return xerrors .Errorf ("beacon at fork point invalid: (%v, %v): %w" ,
62
- h .BeaconEntries [1 ], h .BeaconEntries [0 ], err )
63
- }
64
- return nil
65
- }
66
- }
54
+ // {
55
+ // parentBeacon := bSchedule.BeaconForEpoch(parentEpoch)
56
+ // currBeacon := bSchedule.BeaconForEpoch(h.Height)
57
+ // if parentBeacon != currBeacon {
58
+ // if len(h.BeaconEntries) != 2 {
59
+ // return xerrors.Errorf("expected two beacon entries at beacon fork, got %d", len(h.BeaconEntries))
60
+ // }
61
+ // err := currBeacon.VerifyEntry(h.BeaconEntries[1], h.BeaconEntries[0])
62
+ // if err != nil {
63
+ // return xerrors.Errorf("beacon at fork point invalid: (%v, %v): %w",
64
+ // h.BeaconEntries[1], h.BeaconEntries[0], err)
65
+ // }
66
+ // return nil
67
+ // }
68
+ // }
67
69
68
- // TODO: fork logic
69
70
b := bSchedule .BeaconForEpoch (h .Height )
70
71
maxRound := b .MaxBeaconRoundForEpoch (nv , h .Height )
72
+ // We don't expect to ever actually meet this condition
71
73
if maxRound == prevEntry .Round {
72
74
if len (h .BeaconEntries ) != 0 {
73
75
return xerrors .Errorf ("expected not to have any beacon entries in this block, got %d" , len (h .BeaconEntries ))
@@ -79,13 +81,23 @@ func ValidateBlockValues(bSchedule Schedule, nv network.Version, h *types.BlockH
79
81
return xerrors .Errorf ("expected to have beacon entries in this block, but didn't find any" )
80
82
}
81
83
84
+ if nv >= network .Version22 && len (h .BeaconEntries ) != 1 {
85
+ return xerrors .Errorf ("exactly one beacon entry expected for network version %d, got %d entries" , nv , len (h .BeaconEntries ))
86
+ }
87
+
88
+ if nv < network .Version22 && prevEntry .Round == 0 {
89
+ // This basically means that the drand entry of the first non-genesis tipset isn't verified IF we are starting on Drand mainnet (the "chained" drand)
90
+ // Networks that start on drand quicknet, or other unchained randomness sources, will still verify it
91
+ return nil
92
+ }
93
+
82
94
last := h .BeaconEntries [len (h .BeaconEntries )- 1 ]
83
95
if last .Round != maxRound {
84
96
return xerrors .Errorf ("expected final beacon entry in block to be at round %d, got %d" , maxRound , last .Round )
85
97
}
86
98
87
99
for i , e := range h .BeaconEntries {
88
- if err := b .VerifyEntry (e , prevEntry ); err != nil {
100
+ if err := b .VerifyEntry (e , prevEntry . Data ); err != nil {
89
101
return xerrors .Errorf ("beacon entry %d (%d - %x (%d)) was invalid: %w" , i , e .Round , e .Data , len (e .Data ), err )
90
102
}
91
103
prevEntry = e
@@ -95,34 +107,35 @@ func ValidateBlockValues(bSchedule Schedule, nv network.Version, h *types.BlockH
95
107
}
96
108
97
109
func BeaconEntriesForBlock (ctx context.Context , bSchedule Schedule , nv network.Version , epoch abi.ChainEpoch , parentEpoch abi.ChainEpoch , prev types.BeaconEntry ) ([]types.BeaconEntry , error ) {
98
- {
99
- parentBeacon := bSchedule .BeaconForEpoch (parentEpoch )
100
- currBeacon := bSchedule .BeaconForEpoch (epoch )
101
- if parentBeacon != currBeacon {
102
- // Fork logic
103
- round := currBeacon .MaxBeaconRoundForEpoch (nv , epoch )
104
- out := make ([]types.BeaconEntry , 2 )
105
- rch := currBeacon .Entry (ctx , round - 1 )
106
- res := <- rch
107
- if res .Err != nil {
108
- return nil , xerrors .Errorf ("getting entry %d returned error: %w" , round - 1 , res .Err )
109
- }
110
- out [0 ] = res .Entry
111
- rch = currBeacon .Entry (ctx , round )
112
- res = <- rch
113
- if res .Err != nil {
114
- return nil , xerrors .Errorf ("getting entry %d returned error: %w" , round , res .Err )
115
- }
116
- out [1 ] = res .Entry
117
- return out , nil
118
- }
119
- }
110
+ // {
111
+ // parentBeacon := bSchedule.BeaconForEpoch(parentEpoch)
112
+ // currBeacon := bSchedule.BeaconForEpoch(epoch)
113
+ // if parentBeacon != currBeacon {
114
+ // // Fork logic
115
+ // round := currBeacon.MaxBeaconRoundForEpoch(nv, epoch)
116
+ // out := make([]types.BeaconEntry, 2)
117
+ // rch := currBeacon.Entry(ctx, prev.Round )
118
+ // res := <-rch
119
+ // if res.Err != nil {
120
+ // return nil, xerrors.Errorf("getting entry %d returned error: %w", round-1, res.Err)
121
+ // }
122
+ // out[0] = res.Entry
123
+ // rch = currBeacon.Entry(ctx, round)
124
+ // res = <-rch
125
+ // if res.Err != nil {
126
+ // return nil, xerrors.Errorf("getting entry %d returned error: %w", round, res.Err)
127
+ // }
128
+ // out[1] = res.Entry
129
+ // return out, nil
130
+ // }
131
+ // }
120
132
121
133
beacon := bSchedule .BeaconForEpoch (epoch )
122
134
123
135
start := build .Clock .Now ()
124
136
125
137
maxRound := beacon .MaxBeaconRoundForEpoch (nv , epoch )
138
+ // We don't expect this to ever be the case
126
139
if maxRound == prev .Round {
127
140
return nil , nil
128
141
}
@@ -132,6 +145,21 @@ func BeaconEntriesForBlock(ctx context.Context, bSchedule Schedule, nv network.V
132
145
prev .Round = maxRound - 1
133
146
}
134
147
148
+ // We only ever need one entry after nv22 (FIP-0063)
149
+ if nv >= network .Version22 {
150
+ rch := beacon .Entry (ctx , maxRound )
151
+ select {
152
+ case resp := <- rch :
153
+ if resp .Err != nil {
154
+ return nil , xerrors .Errorf ("beacon entry request returned error: %w" , resp .Err )
155
+ }
156
+
157
+ return []types.BeaconEntry {resp .Entry }, nil
158
+ case <- ctx .Done ():
159
+ return nil , xerrors .Errorf ("context timed out waiting on beacon entry to come back for epoch %d: %w" , epoch , ctx .Err ())
160
+ }
161
+ }
162
+
135
163
cur := maxRound
136
164
var out []types.BeaconEntry
137
165
for cur > prev .Round {
0 commit comments