@@ -15,6 +15,7 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
15
15
alias LambdaEthereumConsensus.P2P.Gossip.BeaconBlock
16
16
alias LambdaEthereumConsensus.P2P.Gossip.BlobSideCar
17
17
alias LambdaEthereumConsensus.P2P.Gossip.OperationsCollector
18
+ alias LambdaEthereumConsensus.P2P.IncomingRequestsHandler
18
19
alias LambdaEthereumConsensus.P2P.Peerbook
19
20
alias LambdaEthereumConsensus.P2p.Requests
20
21
alias LambdaEthereumConsensus.StateTransition.Misc
@@ -62,6 +63,7 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
62
63
| { :discovery_addr , String . t ( ) }
63
64
| { :bootnodes , [ String . t ( ) ] }
64
65
| { :join_init_topics , boolean ( ) }
66
+ | { :enable_request_handlers , boolean ( ) }
65
67
66
68
@ type node_identity ( ) :: % {
67
69
peer_id: binary ( ) ,
@@ -116,15 +118,15 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
116
118
|> Map . take ( [ :peer_id , :pretty_peer_id , :enr , :p2p_addresses , :discovery_addresses ] )
117
119
end
118
120
119
- @ doc """
120
- Sets a Req/Resp handler for the given protocol ID. After this call,
121
- peer requests are sent to the current process' mailbox. To handle them,
122
- use `handle_request/0`.
123
- """
124
- @ spec set_handler ( GenServer . server ( ) , String . t ( ) ) :: :ok | { :error , String . t ( ) }
125
- def set_handler ( pid \\ __MODULE__ , protocol_id ) do
121
+ # Sets libp2pport as the Req/Resp handler for the given protocol ID.
122
+ @ spec set_handler ( String . t ( ) , port ( ) ) :: boolean ( )
123
+ defp set_handler ( protocol_id , port ) do
126
124
:telemetry . execute ( [ :port , :message ] , % { } , % { function: "set_handler" , direction: "elixir->" } )
127
- call_command ( pid , { :set_handler , % SetHandler { protocol_id: protocol_id } } )
125
+
126
+ c = { :set_handler , % SetHandler { protocol_id: protocol_id } }
127
+ data = Command . encode ( % Command { c: c } )
128
+
129
+ send_data ( port , data )
128
130
end
129
131
130
132
@ doc """
@@ -166,27 +168,15 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
166
168
GenServer . cast ( pid , { :send_request , peer_id , protocol_id , message , handler } )
167
169
end
168
170
169
- @ doc """
170
- Returns the next request received by the server for registered handlers
171
- on the current process. If there are no requests, it waits for one.
172
- """
173
- @ spec handle_request ( ) :: { String . t ( ) , String . t ( ) , binary ( ) }
174
- def handle_request ( ) do
175
- receive do
176
- { :request , { _protocol_id , _message_id , _message } = request } -> request
177
- end
178
- end
179
-
180
- @ doc """
181
- Sends a response for the request with the given message ID.
182
- """
183
- @ spec send_response ( GenServer . server ( ) , String . t ( ) , binary ( ) ) ::
184
- :ok | { :error , String . t ( ) }
185
- def send_response ( pid \\ __MODULE__ , request_id , response ) do
171
+ # Sends a response for the request with the given message ID.
172
+ @ spec send_response ( { String . t ( ) , binary ( ) } , port ( ) ) :: boolean ( )
173
+ defp send_response ( { request_id , response } , port ) do
186
174
:telemetry . execute ( [ :port , :message ] , % { } , % { function: "send_response" , direction: "elixir->" } )
187
175
188
- c = % SendResponse { request_id: request_id , message: response }
189
- call_command ( pid , { :send_response , c } )
176
+ c = { :send_response , % SendResponse { request_id: request_id , message: response } }
177
+ data = Command . encode ( % Command { c: c } )
178
+
179
+ send_data ( port , data )
190
180
end
191
181
192
182
@ doc """
@@ -299,6 +289,12 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
299
289
OperationsCollector . init ( )
300
290
end
301
291
292
+ @ spec enable_request_handlers ( port ( ) ) :: :ok | { :error , String . t ( ) }
293
+ defp enable_request_handlers ( port ) do
294
+ IncomingRequestsHandler . protocol_ids ( )
295
+ |> Enum . each ( fn protocol_id -> set_handler ( protocol_id , port ) end )
296
+ end
297
+
302
298
def add_block ( pid \\ __MODULE__ , block ) , do: GenServer . cast ( pid , { :add_block , block } )
303
299
304
300
########################
@@ -308,6 +304,7 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
308
304
@ impl GenServer
309
305
def init ( args ) do
310
306
{ join_init_topics , args } = Keyword . pop ( args , :join_init_topics , false )
307
+ { enable_request_handlers , args } = Keyword . pop ( args , :enable_request_handlers , false )
311
308
312
309
port = Port . open ( { :spawn , @ port_name } , [ :binary , { :packet , 4 } , :exit_status ] )
313
310
@@ -319,6 +316,7 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
319
316
|> then ( & send_data ( port , & 1 ) )
320
317
321
318
if join_init_topics , do: join_init_topics ( port )
319
+ if enable_request_handlers , do: enable_request_handlers ( port )
322
320
323
321
Peerbook . init ( )
324
322
@@ -412,15 +410,21 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
412
410
defp handle_notification (
413
411
% Request {
414
412
protocol_id: protocol_id ,
415
- handler: handler ,
416
413
request_id: request_id ,
417
414
message: message
418
415
} ,
419
- state
416
+ % { port: port } = state
420
417
) do
421
418
:telemetry . execute ( [ :port , :message ] , % { } , % { function: "request" , direction: "->elixir" } )
422
- handler_pid = :erlang . binary_to_term ( handler )
423
- send ( handler_pid , { :request , { protocol_id , request_id , message } } )
419
+
420
+ case IncomingRequestsHandler . handle ( protocol_id , request_id , message ) do
421
+ { :ok , response } ->
422
+ send_response ( response , port )
423
+
424
+ { :error , reason } ->
425
+ Logger . error ( "[Libp2pPort] Error handling request. Reason: #{ inspect ( reason ) } " )
426
+ end
427
+
424
428
state
425
429
end
426
430
0 commit comments