@@ -7,16 +7,35 @@ defmodule LambdaEthereumConsensus.P2P.ReqResp do
7
7
alias LambdaEthereumConsensus.P2P
8
8
alias LambdaEthereumConsensus.SszEx
9
9
10
+ defmodule Error do
11
+ @ moduledoc """
12
+ Error messages for Req/Resp domain.
13
+ """
14
+ defstruct [ :code , :message ]
15
+ @ type t :: % __MODULE__ { code: 1 .. 255 , message: binary ( ) }
16
+
17
+ defp parse_code ( 1 ) , do: "InvalidRequest"
18
+ defp parse_code ( 2 ) , do: "ServerError"
19
+ defp parse_code ( 3 ) , do: "ResourceUnavailable"
20
+ defp parse_code ( n ) , do: "#{ n } "
21
+
22
+ def format ( % Error { code: code , message: message } ) do
23
+ "#{ parse_code ( code ) } : #{ message } "
24
+ end
25
+
26
+ defimpl String.Chars , for: __MODULE__ do
27
+ def to_string ( error ) , do: Error . format ( error )
28
+ end
29
+ end
30
+
10
31
## Encoding
11
32
12
33
@ type context_bytes :: binary ( )
13
34
@ type encodable :: { any ( ) , SszEx . schema ( ) } | struct ( )
14
- @ type error_code :: 1 .. 255
15
- @ type error_message :: binary ( )
16
35
17
36
@ type response_payload ::
18
37
{ :ok , { encodable ( ) , context_bytes ( ) } }
19
- | { :error , { error_code ( ) , error_message ( ) } }
38
+ | { :error , Error . t ( ) }
20
39
21
40
@ spec encode_response ( [ response_payload ( ) ] ) :: binary ( )
22
41
def encode_response ( responses ) do
@@ -35,7 +54,10 @@ defmodule LambdaEthereumConsensus.P2P.ReqResp do
35
54
def encode_ok ( { response , ssz_schema } , context_bytes ) ,
36
55
do: encode ( << 0 >> , context_bytes , { response , ssz_schema } )
37
56
38
- @ spec encode_error ( error_code ( ) , error_message ( ) ) :: binary ( )
57
+ @ spec encode_error ( Error . t ( ) ) :: binary ( )
58
+ def encode_error ( % Error { code: code , message: message } ) , do: encode_error ( code , message )
59
+
60
+ @ spec encode_error ( 1 .. 255 , binary ( ) ) :: binary ( )
39
61
def encode_error ( status_code , error_message ) ,
40
62
do: encode ( << status_code >> , << >> , { error_message , TypeAliases . error_message ( ) } )
41
63
@@ -52,7 +74,8 @@ defmodule LambdaEthereumConsensus.P2P.ReqResp do
52
74
53
75
## Decoding
54
76
55
- @ spec decode_response ( binary ( ) , SszEx . schema ( ) ) :: { :ok , [ any ( ) ] } | { :error , String . t ( ) }
77
+ @ spec decode_response ( binary ( ) , SszEx . schema ( ) ) ::
78
+ { :ok , [ any ( ) ] } | { :error , String . t ( ) } | { :error , Error . t ( ) }
56
79
def decode_response ( response_chunk , ssz_schema ) do
57
80
with { :ok , chunks } <- split_response ( response_chunk ) do
58
81
# TODO: handle errors
@@ -69,7 +92,7 @@ defmodule LambdaEthereumConsensus.P2P.ReqResp do
69
92
end
70
93
end
71
94
72
- @ spec split_response ( binary ) :: { :ok , [ binary ( ) ] } | { :error , String . t ( ) }
95
+ @ spec split_response ( binary ) :: { :ok , [ binary ( ) ] } | { :error , String . t ( ) } | { :error , Error . t ( ) }
73
96
def split_response ( response_chunk ) do
74
97
# TODO: the fork_context should be computed depending on the block's slot
75
98
fork_context = BeaconChain . get_fork_digest ( )
@@ -86,8 +109,8 @@ defmodule LambdaEthereumConsensus.P2P.ReqResp do
86
109
<< 0 , wrong_context :: binary - size ( 4 ) >> <> _ ->
87
110
{ :error , "wrong context: #{ Base . encode16 ( wrong_context ) } " }
88
111
89
- << error_code >> <> error_message ->
90
- { :error , { error_code , decode_error_message ( error_message ) } }
112
+ << error_code >> <> message ->
113
+ decode_error ( error_code , message )
91
114
end
92
115
end
93
116
@@ -114,10 +137,15 @@ defmodule LambdaEthereumConsensus.P2P.ReqResp do
114
137
@ spec decode_response_chunk ( binary ( ) , SszEx . schema ( ) ) ::
115
138
{ :ok , any ( ) }
116
139
| { :error , String . t ( ) }
117
- | { :error , { error_code ( ) , { :ok , error_message ( ) } } }
118
- | { :error , { error_code ( ) , { :error , String . t ( ) } } }
140
+ | { :error , Error . t ( ) }
119
141
def decode_response_chunk ( << 0 >> <> chunk , ssz_schema ) , do: decode_request ( chunk , ssz_schema )
120
142
121
- def decode_response_chunk ( << code >> <> message , _ ) ,
122
- do: { :error , { code , decode_error_message ( message ) } }
143
+ def decode_response_chunk ( << code >> <> message , _ ) , do: decode_error ( code , message )
144
+
145
+ @ spec decode_error ( 1 .. 255 , binary ( ) ) :: { :error , String . t ( ) } | { :error , Error . t ( ) }
146
+ defp decode_error ( code , encoded_message ) do
147
+ with { :ok , error_message } <- decode_error_message ( encoded_message ) do
148
+ { :error , % Error { code: code , message: error_message } }
149
+ end
150
+ end
123
151
end
0 commit comments