1
+ mod middleware;
1
2
#[ warn( unused_imports) ]
2
3
#[ warn( unused_variables) ]
3
4
mod responses;
@@ -6,26 +7,25 @@ mod routes;
6
7
#[ cfg( test) ]
7
8
mod test;
8
9
9
- use anyhow:: anyhow;
10
- use bls_on_arkworks:: { point_to_pubkey, types:: G1ProjectivePoint } ;
11
- use log:: debug;
12
- use reqwest:: Client ;
13
- use std:: marker:: PhantomData ;
14
- use sync_committee_primitives:: {
15
- consensus_types:: { BeaconBlock , BeaconBlockHeader , BeaconState , Checkpoint , Validator } ,
16
- types:: VerifierState ,
17
- } ;
18
-
19
10
use crate :: {
11
+ middleware:: SwitchProviderMiddleware ,
20
12
responses:: {
21
13
finality_checkpoint_response:: FinalityCheckpoint ,
22
14
sync_committee_response:: NodeSyncCommittee ,
23
15
} ,
24
16
routes:: * ,
25
17
} ;
18
+ use anyhow:: anyhow;
19
+ use bls_on_arkworks:: { point_to_pubkey, types:: G1ProjectivePoint } ;
20
+ use log:: trace;
26
21
use primitive_types:: H256 ;
22
+ use reqwest:: { Client , Url } ;
23
+ use reqwest_chain:: ChainMiddleware ;
24
+ use reqwest_middleware:: { ClientBuilder , ClientWithMiddleware } ;
27
25
use ssz_rs:: { Merkleized , Node } ;
26
+ use std:: marker:: PhantomData ;
28
27
use sync_committee_primitives:: {
28
+ consensus_types:: { BeaconBlock , BeaconBlockHeader , BeaconState , Checkpoint , Validator } ,
29
29
constants:: {
30
30
BlsPublicKey , Config , Root , BLOCK_ROOTS_INDEX , BYTES_PER_LOGS_BLOOM ,
31
31
EPOCHS_PER_HISTORICAL_VECTOR , EPOCHS_PER_SLASHINGS_VECTOR , ETH1_DATA_VOTES_BOUND ,
@@ -39,7 +39,7 @@ use sync_committee_primitives::{
39
39
deneb:: MAX_BLOB_COMMITMENTS_PER_BLOCK ,
40
40
types:: {
41
41
AncestryProof , BlockRootsProof , ExecutionPayloadProof , FinalityProof , SyncCommitteeUpdate ,
42
- VerifierStateUpdate ,
42
+ VerifierState , VerifierStateUpdate ,
43
43
} ,
44
44
util:: {
45
45
compute_epoch_at_slot, compute_sync_committee_period_at_slot,
@@ -63,43 +63,68 @@ pub type BeaconStateType = BeaconState<
63
63
> ;
64
64
65
65
pub struct SyncCommitteeProver < C : Config > {
66
- pub node_url : String ,
67
- pub client : Client ,
66
+ pub primary_url : String ,
67
+ pub providers : Vec < String > ,
68
+ pub client : ClientWithMiddleware ,
68
69
pub phantom : PhantomData < C > ,
69
70
}
70
71
71
72
impl < C : Config > Clone for SyncCommitteeProver < C > {
72
73
fn clone ( & self ) -> Self {
73
- Self { node_url : self . node_url . clone ( ) , client : self . client . clone ( ) , phantom : PhantomData }
74
+ Self {
75
+ primary_url : self . primary_url . clone ( ) ,
76
+ client : self . client . clone ( ) ,
77
+ providers : self . providers . clone ( ) ,
78
+ phantom : PhantomData ,
79
+ }
74
80
}
75
81
}
76
82
77
83
impl < C : Config > SyncCommitteeProver < C > {
78
- pub fn new ( node_url : String ) -> Self {
79
- let client = Client :: new ( ) ;
80
-
81
- SyncCommitteeProver :: < C > { node_url, client, phantom : PhantomData }
84
+ pub fn new ( providers : Vec < String > ) -> Self {
85
+ let client = ClientBuilder :: new ( Client :: new ( ) )
86
+ . with ( ChainMiddleware :: new ( SwitchProviderMiddleware :: _new ( providers. clone ( ) ) ) )
87
+ . build ( ) ;
88
+
89
+ SyncCommitteeProver :: < C > {
90
+ primary_url : providers. get ( 0 ) . expect ( "There must be atleast one provider" ) . clone ( ) ,
91
+ providers,
92
+ client,
93
+ phantom : PhantomData ,
94
+ }
82
95
}
83
96
84
97
pub async fn fetch_finalized_checkpoint (
85
98
& self ,
86
99
state_id : Option < & str > ,
87
100
) -> Result < FinalityCheckpoint , anyhow:: Error > {
88
- let full_url = self . generate_route ( & finality_checkpoints ( state_id. unwrap_or ( "head" ) ) ) ;
89
- let response = self . client . get ( full_url) . send ( ) . await ?;
90
-
91
- let response_data =
92
- response. json :: < responses:: finality_checkpoint_response:: Response > ( ) . await ?;
101
+ let full_url = self . generate_route ( & finality_checkpoints ( state_id. unwrap_or ( "head" ) ) ) ?;
102
+ let response = self
103
+ . client
104
+ . get ( full_url)
105
+ . send ( )
106
+ . await
107
+ . map_err ( |e| anyhow ! ( "Failed to fetch finalized checkpoint due to error {e:?}" ) ) ?;
108
+
109
+ let response_data = response
110
+ . json :: < responses:: finality_checkpoint_response:: Response > ( )
111
+ . await
112
+ . map_err ( |e| anyhow ! ( "Failed to fetch finalized checkpoint due to error {e:?}" ) ) ?;
93
113
Ok ( response_data. data )
94
114
}
95
115
96
116
pub async fn fetch_header ( & self , block_id : & str ) -> Result < BeaconBlockHeader , anyhow:: Error > {
97
117
let path = header_route ( block_id) ;
98
- let full_url = self . generate_route ( & path) ;
99
- let response = self . client . get ( full_url) . send ( ) . await ?;
118
+ let full_url = self . generate_route ( & path) ?;
119
+ let response =
120
+ self . client . get ( full_url) . send ( ) . await . map_err ( |e| {
121
+ anyhow ! ( "Failed to fetch header with id {block_id} due to error {e:?}" )
122
+ } ) ?;
100
123
101
- let response_data =
102
- response. json :: < responses:: beacon_block_header_response:: Response > ( ) . await ?;
124
+ let response_data = response
125
+ . json :: < responses:: beacon_block_header_response:: Response > ( )
126
+ . await
127
+ . map_err ( |e| anyhow ! ( "Failed to fetch header with id {block_id} due to error {e:?}" ) ) ?;
103
128
104
129
let beacon_block_header = response_data. data . header . message ;
105
130
@@ -129,11 +154,17 @@ impl<C: Config> SyncCommitteeProver<C> {
129
154
anyhow:: Error ,
130
155
> {
131
156
let path = block_route ( block_id) ;
132
- let full_url = self . generate_route ( & path) ;
157
+ let full_url = self . generate_route ( & path) ? ;
133
158
134
- let response = self . client . get ( full_url) . send ( ) . await ?;
159
+ let response =
160
+ self . client . get ( full_url) . send ( ) . await . map_err ( |e| {
161
+ anyhow ! ( "Failed to fetch block with id {block_id} due to error {e:?}" )
162
+ } ) ?;
135
163
136
- let response_data = response. json :: < responses:: beacon_block_response:: Response > ( ) . await ?;
164
+ let response_data = response
165
+ . json :: < responses:: beacon_block_response:: Response > ( )
166
+ . await
167
+ . map_err ( |e| anyhow ! ( "Failed to fetch block with id {block_id} due to error {e:?}" ) ) ?;
137
168
138
169
let beacon_block = response_data. data . message ;
139
170
@@ -145,7 +176,7 @@ impl<C: Config> SyncCommitteeProver<C> {
145
176
state_id : & str ,
146
177
) -> Result < NodeSyncCommittee , anyhow:: Error > {
147
178
let path = sync_committee_route ( state_id) ;
148
- let full_url = self . generate_route ( & path) ;
179
+ let full_url = self . generate_route ( & path) ? ;
149
180
150
181
let response = self . client . get ( full_url) . send ( ) . await ?;
151
182
@@ -162,7 +193,7 @@ impl<C: Config> SyncCommitteeProver<C> {
162
193
validator_index : & str ,
163
194
) -> Result < Validator , anyhow:: Error > {
164
195
let path = validator_route ( state_id, validator_index) ;
165
- let full_url = self . generate_route ( & path) ;
196
+ let full_url = self . generate_route ( & path) ? ;
166
197
167
198
let response = self . client . get ( full_url) . send ( ) . await ?;
168
199
@@ -178,19 +209,27 @@ impl<C: Config> SyncCommitteeProver<C> {
178
209
state_id : & str ,
179
210
) -> Result < BeaconStateType , anyhow:: Error > {
180
211
let path = beacon_state_route ( state_id) ;
181
- let full_url = self . generate_route ( & path) ;
212
+ let full_url = self . generate_route ( & path) ? ;
182
213
183
- let response = self . client . get ( full_url) . send ( ) . await ?;
214
+ let response = self . client . get ( full_url) . send ( ) . await . map_err ( |e| {
215
+ anyhow ! ( "Failed to fetch beacon state with id {state_id} due to error {e:?}" )
216
+ } ) ?;
184
217
185
- let response_data = response. json :: < responses:: beacon_state_response:: Response > ( ) . await ?;
218
+ let response_data = response
219
+ . json :: < responses:: beacon_state_response:: Response > ( )
220
+ . await
221
+ . map_err ( |e| {
222
+ anyhow ! ( "Failed to fetch beacon state with id {state_id} due to error {e:?}" )
223
+ } ) ?;
186
224
187
225
let beacon_state = response_data. data ;
188
226
189
227
Ok ( beacon_state)
190
228
}
191
229
192
- fn generate_route ( & self , path : & str ) -> String {
193
- format ! ( "{}{}" , self . node_url. clone( ) , path)
230
+ fn generate_route ( & self , path : & str ) -> Result < Url , anyhow:: Error > {
231
+ let url = Url :: parse ( & format ! ( "{}{}" , self . primary_url. clone( ) , path) ) ?;
232
+ Ok ( url)
194
233
}
195
234
196
235
/// Fetches the latest finality update that can be verified by (state_period..=state_period+1)
@@ -201,15 +240,15 @@ impl<C: Config> SyncCommitteeProver<C> {
201
240
mut client_state : VerifierState ,
202
241
finality_checkpoint : Checkpoint ,
203
242
latest_block_id : Option < & str > ,
204
- debug_target : & str ,
205
243
) -> Result < Option < VerifierStateUpdate > , anyhow:: Error > {
206
244
if finality_checkpoint. root == Node :: default ( ) ||
207
245
client_state. latest_finalized_epoch >= finality_checkpoint. epoch
208
246
{
247
+ trace ! ( target: "sync-committee-prover" , "No new epoch finalized yet {}" , finality_checkpoint. epoch) ;
209
248
return Ok ( None ) ;
210
249
}
211
250
212
- debug ! ( target: debug_target , "A new epoch has been finalized {}" , finality_checkpoint. epoch) ;
251
+ trace ! ( target: "sync-committee-prover" , "A new epoch has been finalized {}" , finality_checkpoint. epoch) ;
213
252
// Find the highest block with the a threshhold number of sync committee signatures
214
253
let latest_header = self . fetch_header ( latest_block_id. unwrap_or ( "head" ) ) . await ?;
215
254
let latest_root = latest_header. clone ( ) . hash_tree_root ( ) ?;
@@ -230,7 +269,7 @@ impl<C: Config> SyncCommitteeProver<C> {
230
269
let parent_block_finality_checkpoint =
231
270
self . fetch_finalized_checkpoint ( Some ( & parent_state_id) ) . await ?. finalized ;
232
271
if parent_block_finality_checkpoint. epoch <= client_state. latest_finalized_epoch {
233
- debug ! ( target: "prover" , "Signature block search has reached an invalid epoch {} latest finalized_block_epoch {}" , parent_block_finality_checkpoint. epoch, client_state. latest_finalized_epoch) ;
272
+ trace ! ( target: "sync-committee- prover" , "Search for a block with a valid sync committee signature has reached an invalid epoch {} latest_finalized_block_epoch: {}" , parent_block_finality_checkpoint. epoch, client_state. latest_finalized_epoch) ;
234
273
return Ok ( None ) ;
235
274
}
236
275
@@ -309,6 +348,7 @@ impl<C: Config> SyncCommitteeProver<C> {
309
348
let mut block = loop {
310
349
// Prevent an infinite loop
311
350
if count == 100 {
351
+ log:: trace!( "Prover could not find a suitable block for the sync committee: {period}, syncing will fail" ) ;
312
352
return Err ( anyhow ! ( "Error fetching blocks from selected epoch" ) ) ;
313
353
}
314
354
0 commit comments