@@ -4,13 +4,15 @@ use eth2::types::BlockId as CoreBlockId;
4
4
use std:: fmt;
5
5
use std:: str:: FromStr ;
6
6
use std:: sync:: Arc ;
7
- use types:: { Hash256 , SignedBeaconBlock , SignedBlindedBeaconBlock , Slot } ;
7
+ use types:: { EthSpec , Hash256 , SignedBeaconBlock , SignedBlindedBeaconBlock , Slot } ;
8
8
9
9
/// Wraps `eth2::types::BlockId` and provides a simple way to obtain a block or root for a given
10
10
/// `BlockId`.
11
11
#[ derive( Debug ) ]
12
12
pub struct BlockId ( pub CoreBlockId ) ;
13
13
14
+ type Finalized = bool ;
15
+
14
16
impl BlockId {
15
17
pub fn from_slot ( slot : Slot ) -> Self {
16
18
Self ( CoreBlockId :: Slot ( slot) )
@@ -24,7 +26,7 @@ impl BlockId {
24
26
pub fn root < T : BeaconChainTypes > (
25
27
& self ,
26
28
chain : & BeaconChain < T > ,
27
- ) -> Result < ( Hash256 , ExecutionOptimistic ) , warp:: Rejection > {
29
+ ) -> Result < ( Hash256 , ExecutionOptimistic , Finalized ) , warp:: Rejection > {
28
30
match & self . 0 {
29
31
CoreBlockId :: Head => {
30
32
let ( cached_head, execution_status) = chain
@@ -34,22 +36,23 @@ impl BlockId {
34
36
Ok ( (
35
37
cached_head. head_block_root ( ) ,
36
38
execution_status. is_optimistic_or_invalid ( ) ,
39
+ false ,
37
40
) )
38
41
}
39
- CoreBlockId :: Genesis => Ok ( ( chain. genesis_block_root , false ) ) ,
42
+ CoreBlockId :: Genesis => Ok ( ( chain. genesis_block_root , false , true ) ) ,
40
43
CoreBlockId :: Finalized => {
41
44
let finalized_checkpoint =
42
45
chain. canonical_head . cached_head ( ) . finalized_checkpoint ( ) ;
43
46
let ( _slot, execution_optimistic) =
44
47
checkpoint_slot_and_execution_optimistic ( chain, finalized_checkpoint) ?;
45
- Ok ( ( finalized_checkpoint. root , execution_optimistic) )
48
+ Ok ( ( finalized_checkpoint. root , execution_optimistic, true ) )
46
49
}
47
50
CoreBlockId :: Justified => {
48
51
let justified_checkpoint =
49
52
chain. canonical_head . cached_head ( ) . justified_checkpoint ( ) ;
50
53
let ( _slot, execution_optimistic) =
51
54
checkpoint_slot_and_execution_optimistic ( chain, justified_checkpoint) ?;
52
- Ok ( ( justified_checkpoint. root , execution_optimistic) )
55
+ Ok ( ( justified_checkpoint. root , execution_optimistic, false ) )
53
56
}
54
57
CoreBlockId :: Slot ( slot) => {
55
58
let execution_optimistic = chain
@@ -66,7 +69,14 @@ impl BlockId {
66
69
) )
67
70
} )
68
71
} ) ?;
69
- Ok ( ( root, execution_optimistic) )
72
+ let finalized = * slot
73
+ <= chain
74
+ . canonical_head
75
+ . cached_head ( )
76
+ . finalized_checkpoint ( )
77
+ . epoch
78
+ . start_slot ( T :: EthSpec :: slots_per_epoch ( ) ) ;
79
+ Ok ( ( root, execution_optimistic, finalized) )
70
80
}
71
81
CoreBlockId :: Root ( root) => {
72
82
// This matches the behaviour of other consensus clients (e.g. Teku).
@@ -88,7 +98,20 @@ impl BlockId {
88
98
. is_optimistic_or_invalid_block ( root)
89
99
. map_err ( BeaconChainError :: ForkChoiceError )
90
100
. map_err ( warp_utils:: reject:: beacon_chain_error) ?;
91
- Ok ( ( * root, execution_optimistic) )
101
+ let blinded_block = chain
102
+ . get_blinded_block ( root)
103
+ . map_err ( warp_utils:: reject:: beacon_chain_error) ?
104
+ . ok_or_else ( || {
105
+ warp_utils:: reject:: custom_not_found ( format ! (
106
+ "beacon block with root {}" ,
107
+ root
108
+ ) )
109
+ } ) ?;
110
+ let block_slot = blinded_block. slot ( ) ;
111
+ let finalized = chain
112
+ . is_finalized_block ( root, block_slot)
113
+ . map_err ( warp_utils:: reject:: beacon_chain_error) ?;
114
+ Ok ( ( * root, execution_optimistic, finalized) )
92
115
} else {
93
116
Err ( warp_utils:: reject:: custom_not_found ( format ! (
94
117
"beacon block with root {}" ,
@@ -103,7 +126,14 @@ impl BlockId {
103
126
pub fn blinded_block < T : BeaconChainTypes > (
104
127
& self ,
105
128
chain : & BeaconChain < T > ,
106
- ) -> Result < ( SignedBlindedBeaconBlock < T :: EthSpec > , ExecutionOptimistic ) , warp:: Rejection > {
129
+ ) -> Result <
130
+ (
131
+ SignedBlindedBeaconBlock < T :: EthSpec > ,
132
+ ExecutionOptimistic ,
133
+ Finalized ,
134
+ ) ,
135
+ warp:: Rejection ,
136
+ > {
107
137
match & self . 0 {
108
138
CoreBlockId :: Head => {
109
139
let ( cached_head, execution_status) = chain
@@ -113,10 +143,11 @@ impl BlockId {
113
143
Ok ( (
114
144
cached_head. snapshot . beacon_block . clone_as_blinded ( ) ,
115
145
execution_status. is_optimistic_or_invalid ( ) ,
146
+ false ,
116
147
) )
117
148
}
118
149
CoreBlockId :: Slot ( slot) => {
119
- let ( root, execution_optimistic) = self . root ( chain) ?;
150
+ let ( root, execution_optimistic, finalized ) = self . root ( chain) ?;
120
151
chain
121
152
. get_blinded_block ( & root)
122
153
. map_err ( warp_utils:: reject:: beacon_chain_error)
@@ -128,7 +159,7 @@ impl BlockId {
128
159
slot
129
160
) ) ) ;
130
161
}
131
- Ok ( ( block, execution_optimistic) )
162
+ Ok ( ( block, execution_optimistic, finalized ) )
132
163
}
133
164
None => Err ( warp_utils:: reject:: custom_not_found ( format ! (
134
165
"beacon block with root {}" ,
@@ -137,7 +168,7 @@ impl BlockId {
137
168
} )
138
169
}
139
170
_ => {
140
- let ( root, execution_optimistic) = self . root ( chain) ?;
171
+ let ( root, execution_optimistic, finalized ) = self . root ( chain) ?;
141
172
let block = chain
142
173
. get_blinded_block ( & root)
143
174
. map_err ( warp_utils:: reject:: beacon_chain_error)
@@ -149,7 +180,7 @@ impl BlockId {
149
180
) )
150
181
} )
151
182
} ) ?;
152
- Ok ( ( block, execution_optimistic) )
183
+ Ok ( ( block, execution_optimistic, finalized ) )
153
184
}
154
185
}
155
186
}
@@ -158,7 +189,14 @@ impl BlockId {
158
189
pub async fn full_block < T : BeaconChainTypes > (
159
190
& self ,
160
191
chain : & BeaconChain < T > ,
161
- ) -> Result < ( Arc < SignedBeaconBlock < T :: EthSpec > > , ExecutionOptimistic ) , warp:: Rejection > {
192
+ ) -> Result <
193
+ (
194
+ Arc < SignedBeaconBlock < T :: EthSpec > > ,
195
+ ExecutionOptimistic ,
196
+ Finalized ,
197
+ ) ,
198
+ warp:: Rejection ,
199
+ > {
162
200
match & self . 0 {
163
201
CoreBlockId :: Head => {
164
202
let ( cached_head, execution_status) = chain
@@ -168,10 +206,11 @@ impl BlockId {
168
206
Ok ( (
169
207
cached_head. snapshot . beacon_block . clone ( ) ,
170
208
execution_status. is_optimistic_or_invalid ( ) ,
209
+ false ,
171
210
) )
172
211
}
173
212
CoreBlockId :: Slot ( slot) => {
174
- let ( root, execution_optimistic) = self . root ( chain) ?;
213
+ let ( root, execution_optimistic, finalized ) = self . root ( chain) ?;
175
214
chain
176
215
. get_block ( & root)
177
216
. await
@@ -184,7 +223,7 @@ impl BlockId {
184
223
slot
185
224
) ) ) ;
186
225
}
187
- Ok ( ( Arc :: new ( block) , execution_optimistic) )
226
+ Ok ( ( Arc :: new ( block) , execution_optimistic, finalized ) )
188
227
}
189
228
None => Err ( warp_utils:: reject:: custom_not_found ( format ! (
190
229
"beacon block with root {}" ,
@@ -193,14 +232,14 @@ impl BlockId {
193
232
} )
194
233
}
195
234
_ => {
196
- let ( root, execution_optimistic) = self . root ( chain) ?;
235
+ let ( root, execution_optimistic, finalized ) = self . root ( chain) ?;
197
236
chain
198
237
. get_block ( & root)
199
238
. await
200
239
. map_err ( warp_utils:: reject:: beacon_chain_error)
201
240
. and_then ( |block_opt| {
202
241
block_opt
203
- . map ( |block| ( Arc :: new ( block) , execution_optimistic) )
242
+ . map ( |block| ( Arc :: new ( block) , execution_optimistic, finalized ) )
204
243
. ok_or_else ( || {
205
244
warp_utils:: reject:: custom_not_found ( format ! (
206
245
"beacon block with root {}" ,
0 commit comments