@@ -5,6 +5,7 @@ use std::slice::Iter;
5
5
use hyper:: { self , Body , Client , Method , Request } ;
6
6
use log:: info;
7
7
use serde_json:: { self , Value } ;
8
+ use thiserror:: Error ;
8
9
9
10
use trin_core:: portalnet:: U256 ;
10
11
@@ -78,44 +79,65 @@ impl JsonRpcEndpoint {
78
79
ALL_ENDPOINTS . iter ( )
79
80
}
80
81
81
- pub fn to_jsonrpc ( self ) -> Vec < u8 > {
82
- let data = format ! (
82
+ pub fn to_jsonrpc ( self ) -> String {
83
+ format ! (
83
84
r#"
84
85
{{
85
86
"jsonrpc":"2.0",
86
87
"id": {},
87
88
"method": "{}"
88
89
}}"# ,
89
90
self . id, self . method
90
- ) ;
91
- let v: Value = serde_json:: from_str ( & data) . unwrap ( ) ;
92
- serde_json:: to_vec ( & v) . unwrap ( )
91
+ )
93
92
}
94
93
}
95
94
96
95
pub async fn test_jsonrpc_endpoints_over_ipc ( ) {
97
96
for endpoint in JsonRpcEndpoint :: all_endpoints ( ) {
98
97
info ! ( "Testing over IPC: {:?}" , endpoint. method) ;
99
98
let mut stream = UnixStream :: connect ( "/tmp/trin-jsonrpc.ipc" ) . unwrap ( ) ;
100
- stream. write_all ( & endpoint. to_jsonrpc ( ) ) . unwrap ( ) ;
99
+ let v: Value = serde_json:: from_str ( & endpoint. to_jsonrpc ( ) ) . unwrap ( ) ;
100
+ let data = serde_json:: to_vec ( & v) . unwrap ( ) ;
101
+ stream. write_all ( & data) . unwrap ( ) ;
101
102
stream. flush ( ) . unwrap ( ) ;
102
103
let deser = serde_json:: Deserializer :: from_reader ( stream) ;
103
104
for obj in deser. into_iter :: < Value > ( ) {
104
105
let response_obj = obj. unwrap ( ) ;
105
- let result = response_obj. get ( "result" ) . unwrap ( ) ;
106
- validate_endpoint_response ( endpoint. method , result) ;
106
+ match get_response_result ( response_obj) {
107
+ Ok ( result) => validate_endpoint_response ( endpoint. method , & result) ,
108
+ Err ( msg) => panic ! (
109
+ "Jsonrpc error for {:?} endpoint: {:?}" ,
110
+ endpoint. method, msg
111
+ ) ,
112
+ }
107
113
}
108
114
}
109
115
}
110
116
117
+ #[ derive( Error , Debug ) ]
118
+ pub enum JsonRpcResponseError {
119
+ #[ error( "JsonRpc response contains an error: {0}" ) ]
120
+ Error ( String ) ,
121
+
122
+ #[ error( "Invalid JsonRpc response" ) ]
123
+ Invalid ( ) ,
124
+ }
125
+
126
+ fn get_response_result ( response : Value ) -> Result < Value , JsonRpcResponseError > {
127
+ match response. get ( "result" ) {
128
+ Some ( result) => Ok ( result. clone ( ) ) ,
129
+ None => match response. get ( "error" ) {
130
+ Some ( error) => Err ( JsonRpcResponseError :: Error ( error. to_string ( ) ) ) ,
131
+ None => Err ( JsonRpcResponseError :: Invalid ( ) ) ,
132
+ } ,
133
+ }
134
+ }
135
+
111
136
pub async fn test_jsonrpc_endpoints_over_http ( ) {
112
137
let client = Client :: new ( ) ;
113
138
for endpoint in JsonRpcEndpoint :: all_endpoints ( ) {
114
139
info ! ( "Testing over HTTP: {:?}" , endpoint. method) ;
115
- let json_string = format ! (
116
- r#"{{"jsonrpc":"2.0","id":0,"method":"{}","params":[]}}"# ,
117
- endpoint. method
118
- ) ;
140
+ let json_string = endpoint. to_jsonrpc ( ) ;
119
141
let req = Request :: builder ( )
120
142
. method ( Method :: POST )
121
143
. uri ( "http://127.0.0.1:8545" )
@@ -124,8 +146,13 @@ pub async fn test_jsonrpc_endpoints_over_http() {
124
146
. unwrap ( ) ;
125
147
let resp = client. request ( req) . await . unwrap ( ) ;
126
148
let body = hyper:: body:: to_bytes ( resp. into_body ( ) ) . await . unwrap ( ) ;
127
- let body_json: Value = serde_json:: from_slice ( & body) . unwrap ( ) ;
128
- let result = body_json. get ( "result" ) . unwrap ( ) ;
129
- validate_endpoint_response ( endpoint. method , result) ;
149
+ let response_obj: Value = serde_json:: from_slice ( & body) . unwrap ( ) ;
150
+ match get_response_result ( response_obj) {
151
+ Ok ( result) => validate_endpoint_response ( endpoint. method , & result) ,
152
+ Err ( msg) => panic ! (
153
+ "Jsonrpc error for {:?} endpoint: {:?}" ,
154
+ endpoint. method, msg
155
+ ) ,
156
+ }
130
157
}
131
158
}
0 commit comments