1
- use crate :: targeting:: Rules ;
2
- use crate :: validator:: MessageTypes ;
3
- use crate :: { BigNum , Channel , ChannelId , ValidatorId } ;
1
+ use crate :: {
2
+ targeting:: Rules ,
3
+ validator:: Type as MessageType ,
4
+ validator:: { ApproveState , Heartbeat , MessageTypes , NewState } ,
5
+ BigNum , Channel , ChannelId , ValidatorId ,
6
+ } ;
4
7
use chrono:: { DateTime , Utc } ;
5
8
use serde:: { Deserialize , Serialize } ;
6
- use std:: collections:: HashMap ;
7
- use std:: fmt;
8
- use std:: hash:: Hash ;
9
+ use std:: { collections:: HashMap , fmt, hash:: Hash } ;
9
10
10
11
#[ derive( Serialize , Deserialize , Debug , PartialEq , Eq ) ]
11
12
#[ serde( rename_all = "camelCase" ) ]
12
13
pub struct LastApproved {
13
14
/// NewState can be None if the channel is brand new
14
- pub new_state : Option < NewStateValidatorMessage > ,
15
+ pub new_state : Option < MessageResponse < NewState > > ,
15
16
/// ApproveState can be None if the channel is brand new
16
- pub approve_state : Option < ApproveStateValidatorMessage > ,
17
+ pub approve_state : Option < MessageResponse < ApproveState > > ,
17
18
}
18
19
19
20
#[ derive( Serialize , Deserialize , Debug , PartialEq , Eq ) ]
20
- pub struct NewStateValidatorMessage {
21
+ pub struct MessageResponse < T : MessageType > {
21
22
pub from : ValidatorId ,
22
23
pub received : DateTime < Utc > ,
23
- pub msg : MessageTypes ,
24
+ pub msg : message :: Message < T > ,
24
25
}
25
26
26
- #[ derive( Serialize , Deserialize , Debug , PartialEq , Eq ) ]
27
- pub struct ApproveStateValidatorMessage {
28
- pub from : ValidatorId ,
29
- pub received : DateTime < Utc > ,
30
- pub msg : MessageTypes ,
31
- }
27
+ pub mod message {
28
+ use std:: { convert:: TryFrom , ops:: Deref } ;
32
29
33
- #[ derive( Serialize , Deserialize , Debug , PartialEq , Eq ) ]
34
- pub struct HeartbeatValidatorMessage {
35
- pub from : ValidatorId ,
36
- pub received : DateTime < Utc > ,
37
- pub msg : MessageTypes ,
30
+ use crate :: validator:: messages:: * ;
31
+ use serde:: { Deserialize , Serialize } ;
32
+
33
+ #[ derive( Serialize , Deserialize , Clone , Debug , PartialEq , Eq ) ]
34
+ #[ serde( try_from = "MessageTypes" , into = "MessageTypes" ) ]
35
+ pub struct Message < T : Type > ( T ) ;
36
+
37
+ impl < T : Type > Message < T > {
38
+ pub fn new ( message : T ) -> Self {
39
+ Self ( message)
40
+ }
41
+
42
+ pub fn into_inner ( self ) -> T {
43
+ self . 0
44
+ }
45
+ }
46
+
47
+ impl < T : Type > Deref for Message < T > {
48
+ type Target = T ;
49
+
50
+ fn deref ( & self ) -> & Self :: Target {
51
+ & self . 0
52
+ }
53
+ }
54
+
55
+ impl < T : Type > TryFrom < MessageTypes > for Message < T > {
56
+ type Error = MessageTypeError < T > ;
57
+
58
+ fn try_from ( value : MessageTypes ) -> Result < Self , Self :: Error > {
59
+ <T as TryFrom < MessageTypes > >:: try_from ( value) . map ( Self )
60
+ }
61
+ }
62
+
63
+ impl < T : Type > Into < MessageTypes > for Message < T > {
64
+ fn into ( self ) -> MessageTypes {
65
+ self . 0 . into ( )
66
+ }
67
+ }
68
+
69
+ #[ cfg( test) ]
70
+ mod test {
71
+ use super :: * ;
72
+ use crate :: sentry:: MessageResponse ;
73
+ use chrono:: { TimeZone , Utc } ;
74
+ use serde_json:: { from_value, json, to_value} ;
75
+
76
+ #[ test]
77
+ fn de_serialization_of_a_message ( ) {
78
+ let approve_state_message = json ! ( {
79
+ "from" : "0x2892f6C41E0718eeeDd49D98D648C789668cA67d" ,
80
+ "msg" : {
81
+ "type" : "ApproveState" ,
82
+ "stateRoot" : "4739522efc1e81499541621759dadb331eaf08829d6a3851b4b654dfaddc9935" ,
83
+ "signature" : "0x00128a39b715e87475666c3220fc0400bf34a84d24f77571d2b4e1e88b141d52305438156e526ff4fe96b7a13e707ab2f6f3ca00bd928dabc7f516b56cfe6fd61c" ,
84
+ "isHealthy" : true ,
85
+ "exhausted" : false
86
+ } ,
87
+ "received" : "2021-01-05T14:00:48.549Z"
88
+ } ) ;
89
+
90
+ let actual_message: MessageResponse < ApproveState > =
91
+ from_value ( approve_state_message. clone ( ) ) . expect ( "Should deserialize" ) ;
92
+ let expected_message = MessageResponse {
93
+ from : "0x2892f6C41E0718eeeDd49D98D648C789668cA67d" . parse ( ) . expect ( "Valid ValidatorId" ) ,
94
+ received : Utc . ymd ( 2021 , 1 , 5 ) . and_hms_milli ( 14 , 0 , 48 , 549 ) ,
95
+ msg : Message :: new ( ApproveState {
96
+ state_root : "4739522efc1e81499541621759dadb331eaf08829d6a3851b4b654dfaddc9935" . to_string ( ) ,
97
+ signature : "0x00128a39b715e87475666c3220fc0400bf34a84d24f77571d2b4e1e88b141d52305438156e526ff4fe96b7a13e707ab2f6f3ca00bd928dabc7f516b56cfe6fd61c" . to_string ( ) ,
98
+ is_healthy : true ,
99
+ exhausted : false ,
100
+ } ) ,
101
+ } ;
102
+
103
+ pretty_assertions:: assert_eq!( expected_message, actual_message) ;
104
+ pretty_assertions:: assert_eq!(
105
+ to_value( expected_message) . expect( "should serialize" ) ,
106
+ approve_state_message
107
+ ) ;
108
+ }
109
+ }
38
110
}
39
111
40
112
#[ serde( tag = "type" , rename_all = "SCREAMING_SNAKE_CASE" ) ]
@@ -119,7 +191,7 @@ pub struct LastApprovedResponse {
119
191
/// None -> withHeartbeat=true wasn't passed
120
192
/// Some(vec![]) (empty vec) or Some(heartbeats) - withHeartbeat=true was passed
121
193
#[ serde( default , skip_serializing_if = "Option::is_none" ) ]
122
- pub heartbeats : Option < Vec < HeartbeatValidatorMessage > > ,
194
+ pub heartbeats : Option < Vec < MessageResponse < Heartbeat > > > ,
123
195
}
124
196
125
197
#[ derive( Serialize , Deserialize , Debug ) ]
@@ -232,16 +304,16 @@ pub mod channel_list {
232
304
233
305
#[ cfg( feature = "postgres" ) ]
234
306
mod postgres {
235
- use super :: {
236
- ApproveStateValidatorMessage , HeartbeatValidatorMessage , NewStateValidatorMessage ,
237
- ValidatorMessage ,
307
+ use super :: { MessageResponse , ValidatorMessage } ;
308
+ use crate :: {
309
+ sentry:: EventAggregate ,
310
+ validator:: { messages:: Type as MessageType , MessageTypes } ,
238
311
} ;
239
- use crate :: sentry:: EventAggregate ;
240
- use crate :: validator:: MessageTypes ;
241
312
use bytes:: BytesMut ;
242
313
use postgres_types:: { accepts, to_sql_checked, IsNull , Json , ToSql , Type } ;
243
- use std:: error:: Error ;
244
- use tokio_postgres:: Row ;
314
+ use serde:: Deserialize ;
315
+ use std:: convert:: TryFrom ;
316
+ use tokio_postgres:: { Error , Row } ;
245
317
246
318
impl From < & Row > for EventAggregate {
247
319
fn from ( row : & Row ) -> Self {
@@ -263,33 +335,20 @@ mod postgres {
263
335
}
264
336
}
265
337
266
- impl From < & Row > for ApproveStateValidatorMessage {
267
- fn from ( row : & Row ) -> Self {
268
- Self {
269
- from : row. get ( "from" ) ,
270
- received : row. get ( "received" ) ,
271
- msg : row. get :: < _ , Json < MessageTypes > > ( "msg" ) . 0 ,
272
- }
273
- }
274
- }
275
-
276
- impl From < & Row > for NewStateValidatorMessage {
277
- fn from ( row : & Row ) -> Self {
278
- Self {
279
- from : row. get ( "from" ) ,
280
- received : row. get ( "received" ) ,
281
- msg : row. get :: < _ , Json < MessageTypes > > ( "msg" ) . 0 ,
282
- }
283
- }
284
- }
338
+ impl < T > TryFrom < & Row > for MessageResponse < T >
339
+ where
340
+ T : MessageType ,
341
+ for < ' de > T : Deserialize < ' de > ,
342
+ {
343
+ type Error = Error ;
285
344
286
- impl From < & Row > for HeartbeatValidatorMessage {
287
- fn from ( row : & Row ) -> Self {
288
- Self {
345
+ fn try_from ( row : & Row ) -> Result < Self , Self :: Error > {
346
+ Ok ( Self {
289
347
from : row. get ( "from" ) ,
290
348
received : row. get ( "received" ) ,
291
- msg : row. get :: < _ , Json < MessageTypes > > ( "msg" ) . 0 ,
292
- }
349
+ // guard against mistakes from wrong Queries
350
+ msg : row. try_get :: < _ , Json < _ > > ( "msg" ) ?. 0 ,
351
+ } )
293
352
}
294
353
}
295
354
@@ -298,7 +357,7 @@ mod postgres {
298
357
& self ,
299
358
ty : & Type ,
300
359
w : & mut BytesMut ,
301
- ) -> Result < IsNull , Box < dyn Error + Sync + Send > > {
360
+ ) -> Result < IsNull , Box < dyn std :: error :: Error + Sync + Send > > {
302
361
Json ( self ) . to_sql ( ty, w)
303
362
}
304
363
0 commit comments