@@ -3,6 +3,10 @@ use std::{fmt, str::FromStr};
3
3
use alloy:: primitives:: { Bytes , B256 } ;
4
4
use serde:: { Deserialize , Serialize } ;
5
5
6
+ use crate :: clients:: common:: ClientError ;
7
+
8
+ use super :: CommonBeaconClient ;
9
+
6
10
#[ derive( Serialize , Debug , Clone , PartialEq ) ]
7
11
pub enum BlockId {
8
12
Head ,
@@ -33,6 +37,9 @@ pub struct BlockBody {
33
37
#[ derive( Deserialize , Debug ) ]
34
38
pub struct BlockMessage {
35
39
pub body : BlockBody ,
40
+ pub parent_root : B256 ,
41
+ #[ serde( deserialize_with = "deserialize_number" ) ]
42
+ pub slot : u32 ,
36
43
}
37
44
38
45
#[ derive( Deserialize , Debug ) ]
@@ -59,11 +66,18 @@ pub struct BlobsResponse {
59
66
60
67
#[ derive( Deserialize , Debug ) ]
61
68
pub struct BlockHeaderResponse {
62
- pub data : BlockHeader ,
69
+ pub data : BlockHeaderData ,
63
70
}
64
71
65
- #[ derive( Deserialize , Debug ) ]
72
+ #[ derive( Deserialize , Debug , Clone ) ]
66
73
pub struct BlockHeader {
74
+ pub root : B256 ,
75
+ pub parent_root : B256 ,
76
+ pub slot : u32 ,
77
+ }
78
+
79
+ #[ derive( Deserialize , Debug ) ]
80
+ pub struct BlockHeaderData {
67
81
pub root : B256 ,
68
82
pub header : InnerBlockHeader ,
69
83
}
@@ -83,6 +97,7 @@ pub struct BlockHeaderMessage {
83
97
pub struct HeadEventData {
84
98
#[ serde( deserialize_with = "deserialize_number" ) ]
85
99
pub slot : u32 ,
100
+ #[ allow( dead_code) ]
86
101
pub block : B256 ,
87
102
}
88
103
@@ -156,3 +171,65 @@ impl From<&Topic> for String {
156
171
}
157
172
}
158
173
}
174
+
175
+ impl From < B256 > for BlockId {
176
+ fn from ( value : B256 ) -> Self {
177
+ BlockId :: Hash ( value)
178
+ }
179
+ }
180
+
181
+ impl From < u32 > for BlockId {
182
+ fn from ( value : u32 ) -> Self {
183
+ BlockId :: Slot ( value)
184
+ }
185
+ }
186
+
187
+ impl From < BlockHeaderResponse > for BlockHeader {
188
+ fn from ( response : BlockHeaderResponse ) -> Self {
189
+ BlockHeader {
190
+ root : response. data . root ,
191
+ parent_root : response. data . header . message . parent_root ,
192
+ slot : response. data . header . message . slot ,
193
+ }
194
+ }
195
+ }
196
+
197
+ #[ derive( Debug , thiserror:: Error ) ]
198
+ pub enum BlockIdResolutionError {
199
+ #[ error( "Block with id '{0}' not found" ) ]
200
+ BlockNotFound ( BlockId ) ,
201
+ #[ error( "Failed to resolve block id '{block_id}'" ) ]
202
+ FailedBlockIdResolution {
203
+ block_id : BlockId ,
204
+ #[ source]
205
+ error : ClientError ,
206
+ } ,
207
+ }
208
+
209
+ pub trait BlockIdResolution {
210
+ async fn resolve_to_slot (
211
+ & self ,
212
+ beacon_client : & dyn CommonBeaconClient ,
213
+ ) -> Result < u32 , BlockIdResolutionError > ;
214
+ }
215
+
216
+ impl BlockIdResolution for BlockId {
217
+ async fn resolve_to_slot (
218
+ & self ,
219
+ beacon_client : & dyn CommonBeaconClient ,
220
+ ) -> Result < u32 , BlockIdResolutionError > {
221
+ match self {
222
+ BlockId :: Slot ( slot) => Ok ( * slot) ,
223
+ _ => match beacon_client
224
+ . get_block_header ( self . clone ( ) . into ( ) )
225
+ . await
226
+ . map_err ( |err| BlockIdResolutionError :: FailedBlockIdResolution {
227
+ block_id : self . clone ( ) ,
228
+ error : err,
229
+ } ) ? {
230
+ Some ( header) => Ok ( header. slot ) ,
231
+ None => Err ( BlockIdResolutionError :: BlockNotFound ( self . clone ( ) ) ) ,
232
+ } ,
233
+ }
234
+ }
235
+ }
0 commit comments