@@ -9,7 +9,6 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
9
9
10
10
use GenServer
11
11
12
- alias LambdaEthereumConsensus.Validator.ValidatorManager
13
12
alias LambdaEthereumConsensus.Beacon.PendingBlocks
14
13
alias LambdaEthereumConsensus.Beacon.SyncBlocks
15
14
alias LambdaEthereumConsensus.ForkChoice
@@ -22,6 +21,7 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
22
21
alias LambdaEthereumConsensus.P2p.Requests
23
22
alias LambdaEthereumConsensus.StateTransition.Misc
24
23
alias LambdaEthereumConsensus.Utils.BitVector
24
+ alias LambdaEthereumConsensus.Validator
25
25
alias Libp2pProto.AddPeer
26
26
alias Libp2pProto.Command
27
27
alias Libp2pProto.Enr
@@ -63,6 +63,7 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
63
63
64
64
@ type init_arg ::
65
65
{ :genesis_time , Types . uint64 ( ) }
66
+ | { :validators , % { } }
66
67
| { :listen_addr , [ String . t ( ) ] }
67
68
| { :enable_discovery , boolean ( ) }
68
69
| { :discovery_addr , String . t ( ) }
@@ -113,6 +114,14 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
113
114
GenServer . cast ( __MODULE__ , { :on_tick , time } )
114
115
end
115
116
117
+ @ spec notify_new_block ( { Types . slot ( ) , Types . root ( ) } ) :: :ok
118
+ def notify_new_block ( data ) do
119
+ # TODO: This is quick workarround to notify the libp2p port about new blocks from within
120
+ # the ForkChoice.recompute_head/1 without moving the validators to the store this
121
+ # allows to deferr that move until we simplify the state and remove duplicates.
122
+ send ( self ( ) , { :new_block , data } )
123
+ end
124
+
116
125
@ doc """
117
126
Retrieves identity info from the underlying LibP2P node.
118
127
"""
@@ -354,6 +363,7 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
354
363
@ impl GenServer
355
364
def init ( args ) do
356
365
{ genesis_time , args } = Keyword . pop! ( args , :genesis_time )
366
+ { validators , args } = Keyword . pop ( args , :validators , % { } )
357
367
{ join_init_topics , args } = Keyword . pop ( args , :join_init_topics , false )
358
368
{ enable_request_handlers , args } = Keyword . pop ( args , :enable_request_handlers , false )
359
369
@@ -379,6 +389,7 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
379
389
{ :ok ,
380
390
% {
381
391
genesis_time: genesis_time ,
392
+ validators: validators ,
382
393
slot_data: nil ,
383
394
port: port ,
384
395
subscribers: % { } ,
@@ -408,7 +419,10 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
408
419
end
409
420
410
421
@ impl GenServer
411
- def handle_cast ( { :on_tick , time } , % { genesis_time: genesis_time } = state ) when time < genesis_time , do: { :noreply , state }
422
+ def handle_cast ( { :on_tick , time } , % { genesis_time: genesis_time } = state )
423
+ when time < genesis_time ,
424
+ do: { :noreply , state }
425
+
412
426
def handle_cast ( { :on_tick , time } , % { genesis_time: genesis_time , slot_data: slot_data } = state ) do
413
427
# TODO: we probably want to remove this from here, but we keep it here to have this serialized
414
428
# with respect to the other fork choice store modifications.
@@ -417,13 +431,11 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
417
431
418
432
new_slot_data = compute_slot ( genesis_time , time )
419
433
420
- if slot_data != new_slot_data do
421
- ValidatorManager . notify_tick ( slot_data )
422
- end
434
+ updated_state = maybe_tick_validators ( slot_data != new_slot_data , new_slot_data , state )
423
435
424
- log_new_slot ( new_slot_data )
436
+ log_new_slot ( slot_data , new_slot_data )
425
437
426
- { :noreply , % { state | slot_data: new_slot_data } }
438
+ { :noreply , updated_state }
427
439
end
428
440
429
441
def handle_cast (
@@ -486,6 +498,13 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
486
498
{ :noreply , new_state }
487
499
end
488
500
501
+ @ impl GenServer
502
+ def handle_info ( { :new_block , data } , % { validators: validators } = state ) do
503
+ updated_validators = notify_validators ( validators , { :new_block , data } )
504
+
505
+ { :noreply , % { state | validators: updated_validators } }
506
+ end
507
+
489
508
@ impl GenServer
490
509
def handle_info ( { _port , { :data , data } } , state ) do
491
510
% Notification { n: { _ , payload } } = Notification . decode ( data )
@@ -707,6 +726,38 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
707
726
end )
708
727
end
709
728
729
+ # Validator related functions
730
+
731
+ defp maybe_tick_validators ( false = _slot_data_changed , _slot_data , state ) , do: state
732
+
733
+ defp maybe_tick_validators ( true , slot_data , % { validators: validators } = state ) do
734
+ updated_validators = notify_validators ( validators , { :on_tick , slot_data } )
735
+
736
+ % { state | slot_data: slot_data , validators: updated_validators }
737
+ end
738
+
739
+ defp notify_validators ( validators , msg ) do
740
+ start_time = System . monotonic_time ( :millisecond )
741
+
742
+ Logger . info ( "[Libp2p] Notifying all Validators with message: #{ inspect ( msg ) } " )
743
+
744
+ updated_validators = Enum . map ( validators , & notify_validator ( & 1 , msg ) )
745
+
746
+ end_time = System . monotonic_time ( :millisecond )
747
+
748
+ Logger . debug (
749
+ "[Validator Manager] #{ inspect ( msg ) } notified to all Validators after #{ end_time - start_time } ms"
750
+ )
751
+
752
+ updated_validators
753
+ end
754
+
755
+ defp notify_validator ( { pubkey , validator } , { :on_tick , slot_data } ) ,
756
+ do: { pubkey , Validator . handle_tick ( slot_data , validator ) }
757
+
758
+ defp notify_validator ( { pubkey , validator } , { :new_block , { slot , head_root } } ) ,
759
+ do: { pubkey , Validator . handle_new_block ( slot , head_root , validator ) }
760
+
710
761
@ spec compute_slot ( Types . uint64 ( ) , Types . uint64 ( ) ) :: slot_data ( )
711
762
defp compute_slot ( genesis_time , time ) do
712
763
# TODO: This was copied as it is from the Clock to convert it into just a Ticker,
@@ -726,12 +777,14 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
726
777
{ slot , slot_third }
727
778
end
728
779
729
- defp log_new_slot ( { slot , :first_third } ) do
780
+ defp log_new_slot ( { slot , _third } , { slot , _third } ) , do: :ok
781
+
782
+ defp log_new_slot ( { _prev_slot , _thrid } , { slot , :first_third } ) do
730
783
# TODO: as with the previous function, this was copied from the Clock module.
731
- # is use :sync, :store as the slot event, probably something to look into.
784
+ # It use :sync, :store as the slot event, probably something to look into.
732
785
:telemetry . execute ( [ :sync , :store ] , % { slot: slot } )
733
786
Logger . info ( "[Libp2p] Slot transition" , slot: slot )
734
787
end
735
788
736
- defp log_new_slot ( _ ) , do: :ok
789
+ defp log_new_slot ( _ , _ ) , do: :ok
737
790
end
0 commit comments