@@ -9,6 +9,8 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
9
9
10
10
use GenServer
11
11
12
+ @ tick_time 1000
13
+
12
14
alias LambdaEthereumConsensus.Beacon.PendingBlocks
13
15
alias LambdaEthereumConsensus.Beacon.SyncBlocks
14
16
alias LambdaEthereumConsensus.ForkChoice
@@ -109,11 +111,6 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
109
111
GenServer . start_link ( __MODULE__ , args , opts )
110
112
end
111
113
112
- @ spec on_tick ( Types . uint64 ( ) ) :: :ok
113
- def on_tick ( time ) do
114
- GenServer . cast ( __MODULE__ , { :on_tick , time } )
115
- end
116
-
117
114
@ spec notify_new_block ( Types . slot ( ) , Types . root ( ) ) :: :ok
118
115
def notify_new_block ( slot , head_root ) do
119
116
# TODO: This is quick workarround to notify the libp2p port about new blocks from within
@@ -403,6 +400,8 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
403
400
"[Optimistic Sync] Waiting #{ @ sync_delay_millis / 1000 } seconds to discover some peers before requesting blocks."
404
401
)
405
402
403
+ schedule_next_tick ( )
404
+
406
405
{ :ok ,
407
406
% {
408
407
genesis_time: genesis_time ,
@@ -435,26 +434,6 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
435
434
{ :noreply , state }
436
435
end
437
436
438
- @ impl GenServer
439
- def handle_cast ( { :on_tick , time } , % { genesis_time: genesis_time } = state )
440
- when time < genesis_time ,
441
- do: { :noreply , state }
442
-
443
- def handle_cast ( { :on_tick , time } , % { genesis_time: genesis_time , slot_data: slot_data } = state ) do
444
- # TODO: we probably want to remove this from here, but we keep it here to have this serialized
445
- # with respect to the other fork choice store modifications.
446
-
447
- ForkChoice . on_tick ( time )
448
-
449
- new_slot_data = compute_slot ( genesis_time , time )
450
-
451
- updated_state = maybe_tick_validators ( slot_data != new_slot_data , new_slot_data , state )
452
-
453
- log_new_slot ( slot_data , new_slot_data )
454
-
455
- { :noreply , updated_state }
456
- end
457
-
458
437
def handle_cast (
459
438
{ :send_request , peer_id , protocol_id , message , handler } ,
460
439
% {
@@ -505,6 +484,14 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
505
484
{ :noreply , state }
506
485
end
507
486
487
+ @ impl GenServer
488
+ def handle_info ( :on_tick , % { genesis_time: genesis_time } = state ) do
489
+ schedule_next_tick ( )
490
+ time = :os . system_time ( :second )
491
+
492
+ { :noreply , on_tick ( time , state ) }
493
+ end
494
+
508
495
@ impl GenServer
509
496
def handle_info ( :sync_blocks , state ) do
510
497
blocks_to_download = SyncBlocks . run ( )
@@ -743,6 +730,23 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
743
730
end )
744
731
end
745
732
733
+ defp on_tick ( time , % { genesis_time: genesis_time } = state ) when time < genesis_time , do: state
734
+
735
+ defp on_tick ( time , % { genesis_time: genesis_time , slot_data: slot_data } = state ) do
736
+ # TODO: we probably want to remove this (ForkChoice.on_tick) from here, but we keep it
737
+ # here to have this serialized with respect to the other fork choice store modifications.
738
+
739
+ ForkChoice . on_tick ( time )
740
+
741
+ new_slot_data = compute_slot ( genesis_time , time )
742
+
743
+ updated_state = maybe_tick_validators ( slot_data != new_slot_data , new_slot_data , state )
744
+
745
+ maybe_log_new_slot ( slot_data , new_slot_data )
746
+
747
+ updated_state
748
+ end
749
+
746
750
defp maybe_tick_validators ( false = _slot_data_changed , _slot_data , state ) , do: state
747
751
748
752
defp maybe_tick_validators ( true , slot_data , % { validators: validators } = state ) do
@@ -773,10 +777,15 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
773
777
defp notify_validator ( { pubkey , validator } , { :new_block , slot , head_root } ) ,
774
778
do: { pubkey , Validator . handle_new_block ( slot , head_root , validator ) }
775
779
776
- @ spec compute_slot ( Types . uint64 ( ) , Types . uint64 ( ) ) :: slot_data ( )
780
+ defp schedule_next_tick ( ) do
781
+ # For millisecond precision
782
+ time_to_next_tick = @ tick_time - rem ( :os . system_time ( :millisecond ) , @ tick_time )
783
+ Process . send_after ( __MODULE__ , :on_tick , time_to_next_tick )
784
+ end
785
+
777
786
defp compute_slot ( genesis_time , time ) do
778
- # TODO: This was copied as it is from the Clock to convert it into just a Ticker,
779
- # slot calculations are spread across modules, we should probably centralize them.
787
+ # TODO: This was copied as it is from the Clock, slot calculations are spread
788
+ # across modules, we should probably centralize them.
780
789
elapsed_time = time - genesis_time
781
790
782
791
slot_thirds = div ( elapsed_time * 3 , ChainSpec . get ( "SECONDS_PER_SLOT" ) )
@@ -792,13 +801,13 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
792
801
{ slot , slot_third }
793
802
end
794
803
795
- defp log_new_slot ( { slot , _third } , { slot , _another_third } ) , do: :ok
804
+ defp maybe_log_new_slot ( { slot , _third } , { slot , _another_third } ) , do: :ok
796
805
797
- defp log_new_slot ( { _prev_slot , _thrid } , { slot , :first_third } ) do
806
+ defp maybe_log_new_slot ( { _prev_slot , _thrid } , { slot , :first_third } ) do
798
807
# TODO: It used :sync, :store as the slot event in the old Clock, double-check.
799
808
:telemetry . execute ( [ :sync , :store ] , % { slot: slot } )
800
809
Logger . info ( "[Libp2p] Slot transition" , slot: slot )
801
810
end
802
811
803
- defp log_new_slot ( _ , _ ) , do: :ok
812
+ defp maybe_log_new_slot ( _ , _ ) , do: :ok
804
813
end
0 commit comments