1
- use crate :: error:: ValidatorWorker ;
1
+ use std:: collections:: HashMap ;
2
+ use std:: fmt;
3
+ use std:: time:: Duration ;
4
+
2
5
use chrono:: { DateTime , Utc } ;
3
- use futures:: future:: try_join_all;
4
- use futures:: future:: TryFutureExt ;
5
- use primitives:: adapter:: Adapter ;
6
+ use futures:: future:: { try_join_all, TryFutureExt } ;
7
+ use reqwest:: { Client , Response } ;
8
+ use slog:: { error, Logger } ;
9
+
10
+ use primitives:: adapter:: { Adapter , AdapterErrorKind , Error as AdapterError } ;
6
11
use primitives:: channel:: SpecValidator ;
7
12
use primitives:: sentry:: {
8
13
ChannelListResponse , EventAggregateResponse , LastApprovedResponse , SuccessResponse ,
9
14
ValidatorMessageResponse ,
10
15
} ;
11
16
use primitives:: validator:: MessageTypes ;
12
- use primitives:: { Channel , Config , ToETHChecksum , ValidatorDesc , ValidatorId } ;
13
- use reqwest:: { Client , Response } ;
14
- use slog:: { error, Logger } ;
15
- use std:: collections:: HashMap ;
16
- use std:: time:: Duration ;
17
+ use primitives:: { Channel , ChannelId , Config , ToETHChecksum , ValidatorDesc , ValidatorId } ;
17
18
18
19
#[ derive( Debug , Clone ) ]
19
20
pub struct SentryApi < T : Adapter > {
@@ -26,17 +27,63 @@ pub struct SentryApi<T: Adapter> {
26
27
pub propagate_to : Vec < ( ValidatorDesc , String ) > ,
27
28
}
28
29
29
- impl < T : Adapter + ' static > SentryApi < T > {
30
+ #[ derive( Debug ) ]
31
+ pub enum Error < AE : AdapterErrorKind > {
32
+ BuildingClient ( reqwest:: Error ) ,
33
+ Request ( reqwest:: Error ) ,
34
+ ValidatorAuthentication ( AdapterError < AE > ) ,
35
+ MissingWhoamiInChannelValidators {
36
+ channel : ChannelId ,
37
+ validators : Vec < ValidatorId > ,
38
+ whoami : ValidatorId ,
39
+ } ,
40
+ }
41
+
42
+ impl < AE : AdapterErrorKind > std:: error:: Error for Error < AE > { }
43
+
44
+ impl < AE : AdapterErrorKind > fmt:: Display for Error < AE > {
45
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
46
+ use Error :: * ;
47
+
48
+ match self {
49
+ BuildingClient ( err) => write ! ( f, "Building client - {}" , err) ,
50
+ Request ( err) => write ! ( f, "Making a request - {}" , err) ,
51
+ ValidatorAuthentication ( err) => {
52
+ write ! ( f, "Getting authentication for validator - {}" , err)
53
+ }
54
+ MissingWhoamiInChannelValidators {
55
+ channel,
56
+ validators,
57
+ whoami,
58
+ } => {
59
+ let validator_ids = validators
60
+ . iter ( )
61
+ . map ( ToString :: to_string)
62
+ . collect :: < Vec < _ > > ( )
63
+ . join ( ", " ) ;
64
+ write ! (
65
+ f,
66
+ "We cannot find validator entry for whoami ({}) in channel {} with validators: {}" ,
67
+ whoami,
68
+ channel,
69
+ validator_ids
70
+ )
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ impl < A : Adapter + ' static > SentryApi < A > {
30
77
pub fn init (
31
- adapter : T ,
78
+ adapter : A ,
32
79
channel : & Channel ,
33
80
config : & Config ,
34
81
logger : Logger ,
35
- ) -> Result < Self , ValidatorWorker > {
82
+ ) -> Result < Self , Error < A :: AdapterError > > {
36
83
let client = Client :: builder ( )
37
84
. timeout ( Duration :: from_millis ( config. fetch_timeout . into ( ) ) )
38
85
. build ( )
39
- . map_err ( |e| ValidatorWorker :: Failed ( format ! ( "building Client error: {}" , e ) ) ) ?;
86
+ . map_err ( Error :: BuildingClient ) ?;
40
87
41
88
// validate that we are to validate the channel
42
89
match channel. spec . validators . find ( adapter. whoami ( ) ) {
@@ -51,12 +98,7 @@ impl<T: Adapter + 'static> SentryApi<T> {
51
98
adapter
52
99
. get_auth ( & validator. id )
53
100
. map ( |auth| ( validator. to_owned ( ) , auth) )
54
- . map_err ( |e| {
55
- ValidatorWorker :: Failed ( format ! (
56
- "Propagation error: get auth failed {}" ,
57
- e
58
- ) )
59
- } )
101
+ . map_err ( Error :: ValidatorAuthentication )
60
102
} )
61
103
. collect :: < Result < Vec < _ > , _ > > ( ) ?;
62
104
@@ -70,28 +112,36 @@ impl<T: Adapter + 'static> SentryApi<T> {
70
112
config : config. to_owned ( ) ,
71
113
} )
72
114
}
73
- SpecValidator :: None => Err ( ValidatorWorker :: Failed (
74
- "We can not find validator entry for whoami" . to_string ( ) ,
75
- ) ) ,
115
+ SpecValidator :: None => Err ( Error :: MissingWhoamiInChannelValidators {
116
+ channel : channel. id ,
117
+ validators : channel
118
+ . spec
119
+ . validators
120
+ . iter ( )
121
+ . map ( |v| v. id . clone ( ) )
122
+ . collect ( ) ,
123
+ whoami : adapter. whoami ( ) . clone ( ) ,
124
+ } ) ,
76
125
}
77
126
}
78
127
128
+ // @TODO: Remove logging & fix `try_join_all` @see: https://github.com/AdExNetwork/adex-validator-stack-rust/issues/278
79
129
pub async fn propagate ( & self , messages : & [ & MessageTypes ] ) {
80
130
let channel_id = format ! ( "0x{}" , hex:: encode( & self . channel. id) ) ;
81
131
if let Err ( e) = try_join_all ( self . propagate_to . iter ( ) . map ( |( validator, auth_token) | {
82
132
propagate_to ( & channel_id, & auth_token, & self . client , & validator, messages)
83
133
} ) )
84
134
. await
85
135
{
86
- error ! ( & self . logger, "Propagation error: {}" , e; "module" => "sentry_interface" , "in" => "SentryApi" ) ;
136
+ error ! ( & self . logger, "Propagation error - {}" , e; "module" => "sentry_interface" , "in" => "SentryApi" ) ;
87
137
}
88
138
}
89
139
90
140
pub async fn get_latest_msg (
91
141
& self ,
92
142
from : & ValidatorId ,
93
143
message_types : & [ & str ] ,
94
- ) -> Result < Option < MessageTypes > , reqwest :: Error > {
144
+ ) -> Result < Option < MessageTypes > , Error < A :: AdapterError > > {
95
145
let message_type = message_types. join ( "+" ) ;
96
146
let url = format ! (
97
147
"{}/validator-messages/{}/{}?limit=1" ,
@@ -104,6 +154,7 @@ impl<T: Adapter + 'static> SentryApi<T> {
104
154
. get ( & url)
105
155
. send ( )
106
156
. and_then ( |res : Response | res. json :: < ValidatorMessageResponse > ( ) )
157
+ . map_err ( Error :: Request )
107
158
. await ?;
108
159
109
160
Ok ( result. validator_messages . first ( ) . map ( |m| m. msg . clone ( ) ) )
@@ -112,38 +163,40 @@ impl<T: Adapter + 'static> SentryApi<T> {
112
163
pub async fn get_our_latest_msg (
113
164
& self ,
114
165
message_types : & [ & str ] ,
115
- ) -> Result < Option < MessageTypes > , reqwest :: Error > {
166
+ ) -> Result < Option < MessageTypes > , Error < A :: AdapterError > > {
116
167
self . get_latest_msg ( self . adapter . whoami ( ) , message_types)
117
168
. await
118
169
}
119
170
120
- pub async fn get_last_approved ( & self ) -> Result < LastApprovedResponse , reqwest :: Error > {
171
+ pub async fn get_last_approved ( & self ) -> Result < LastApprovedResponse , Error < A :: AdapterError > > {
121
172
self . client
122
173
. get ( & format ! ( "{}/last-approved" , self . validator_url) )
123
174
. send ( )
124
175
. and_then ( |res : Response | res. json :: < LastApprovedResponse > ( ) )
176
+ . map_err ( Error :: Request )
125
177
. await
126
178
}
127
179
128
- pub async fn get_last_msgs ( & self ) -> Result < LastApprovedResponse , reqwest :: Error > {
180
+ pub async fn get_last_msgs ( & self ) -> Result < LastApprovedResponse , Error < A :: AdapterError > > {
129
181
self . client
130
182
. get ( & format ! (
131
183
"{}/last-approved?withHeartbeat=true" ,
132
184
self . validator_url
133
185
) )
134
186
. send ( )
135
187
. and_then ( |res : Response | res. json :: < LastApprovedResponse > ( ) )
188
+ . map_err ( Error :: Request )
136
189
. await
137
190
}
138
191
139
192
pub async fn get_event_aggregates (
140
193
& self ,
141
194
after : DateTime < Utc > ,
142
- ) -> Result < EventAggregateResponse , Box < ValidatorWorker > > {
195
+ ) -> Result < EventAggregateResponse , Error < A :: AdapterError > > {
143
196
let auth_token = self
144
197
. adapter
145
198
. get_auth ( self . adapter . whoami ( ) )
146
- . map_err ( |e| Box :: new ( ValidatorWorker :: Failed ( e . to_string ( ) ) ) ) ?;
199
+ . map_err ( Error :: ValidatorAuthentication ) ?;
147
200
148
201
let url = format ! (
149
202
"{}/events-aggregates?after={}" ,
@@ -155,10 +208,10 @@ impl<T: Adapter + 'static> SentryApi<T> {
155
208
. get ( & url)
156
209
. bearer_auth ( & auth_token)
157
210
. send ( )
158
- . map_err ( |e| Box :: new ( ValidatorWorker :: Failed ( e . to_string ( ) ) ) )
211
+ . map_err ( Error :: Request )
159
212
. await ?
160
213
. json ( )
161
- . map_err ( |e| Box :: new ( ValidatorWorker :: Failed ( e . to_string ( ) ) ) )
214
+ . map_err ( Error :: Request )
162
215
. await
163
216
}
164
217
}
0 commit comments