@@ -49,34 +49,49 @@ func FindLastBlockWithExecutionPayload(bc beacon.Client, slotNumber uint64) (bea
4949}
5050
5151func FindNextSubmissionTarget (rp * rocketpool.RocketPool , eth2Config beacon.Eth2Config , bc beacon.Client , ec rocketpool.ExecutionClient , lastSubmissionBlock uint64 , referenceTimestamp int64 , submissionIntervalInSeconds int64 ) (uint64 , time.Time , * types.Header , error ) {
52- // Get the time of the last submission
53- lastSubmissionBlockHeader , err := rp .Client .HeaderByNumber (context .Background (), big .NewInt (int64 (lastSubmissionBlock )))
54- if err != nil {
55- return 0 , time.Time {}, nil , fmt .Errorf ("can't get the latest submission block header: %w" , err )
56- }
52+ lastSubmissionSlotTimestamp := referenceTimestamp
5753
58- // Get the time of the latest block
59- latestEth1Block , err := rp .Client .HeaderByNumber (context .Background (), nil )
60- if err != nil {
61- return 0 , time.Time {}, nil , fmt .Errorf ("can't get the latest block time: %w" , err )
62- }
63- latestBlockTimestamp := int64 (latestEth1Block .Time )
54+ genesisTime := time .Unix (int64 (eth2Config .GenesisTime ), 0 )
55+
56+ if lastSubmissionBlock > 0 {
57+ lastSubmissionBlockHeader , err := rp .Client .HeaderByNumber (context .Background (), big .NewInt (int64 (lastSubmissionBlock )))
58+ if err != nil {
59+ return 0 , time.Time {}, nil , fmt .Errorf ("can't get the latest submission block header: %w" , err )
60+ }
61+
62+ lastSubmissionParent , _ , err := bc .GetBeaconBlock (lastSubmissionBlockHeader .ParentBeaconRoot .Hex ())
63+ if err != nil {
64+ return 0 , time.Time {}, nil , fmt .Errorf ("can't get the parent block: %w" , err )
65+ }
6466
65- if int64 ( lastSubmissionBlockHeader . Time ) + submissionIntervalInSeconds > latestBlockTimestamp {
66- return 0 , time.Time {}, nil , fmt . Errorf ( "not enough time has passed for the next price/balances submission" )
67+ lastSubmissionSlot := lastSubmissionParent . Slot + 1
68+ lastSubmissionSlotTimestamp = genesisTime . Add ( time .Duration (( lastSubmissionSlot ) * eth2Config . SecondsPerSlot ) * time . Second ). Unix ( )
6769 }
6870
69- // Calculate the next submission timestamp
70- submissionTimestamp , err := FindNextSubmissionTimestamp (latestBlockTimestamp , referenceTimestamp , submissionIntervalInSeconds )
71+ beaconHead , err := bc .GetBeaconHead ()
7172 if err != nil {
7273 return 0 , time.Time {}, nil , err
7374 }
75+ headEpoch := beaconHead .Epoch
76+
77+ // Calculate the timestamp at the start of the head epoch
78+ headEpochStartSlot := headEpoch * eth2Config .SlotsPerEpoch
79+ headEpochTimestamp := genesisTime .Add (time .Duration (headEpochStartSlot * eth2Config .SecondsPerSlot ) * time .Second )
80+
81+ // Find the highest valid submissionTimestamp that is <= headTime
82+ maxSubmissionTimestamp := int64 (0 )
83+ n := int64 (0 )
84+ for {
85+ ts := lastSubmissionSlotTimestamp + n * submissionIntervalInSeconds
86+ if ts > headEpochTimestamp .Unix () {
87+ break
88+ }
89+ maxSubmissionTimestamp = ts
90+ n ++
91+ }
7492
75- // Convert the submission timestamp to time.Time
76- nextSubmissionTime := time .Unix (submissionTimestamp , 0 )
77-
78- // Get the Beacon block corresponding to this time
79- genesisTime := time .Unix (int64 (eth2Config .GenesisTime ), 0 )
93+ // Now, use this maxSubmissionTimestamp for slot calculations
94+ nextSubmissionTime := time .Unix (maxSubmissionTimestamp , 0 )
8095 timeSinceGenesis := nextSubmissionTime .Sub (genesisTime )
8196 slotNumber := uint64 (timeSinceGenesis .Seconds ()) / eth2Config .SecondsPerSlot
8297
@@ -94,34 +109,10 @@ func FindNextSubmissionTarget(rp *rocketpool.RocketPool, eth2Config beacon.Eth2C
94109 }
95110 requiredEpoch := slotNumber / eth2Config .SlotsPerEpoch
96111
97- // Check if the required epoch is finalized yet
98- beaconHead , err := bc .GetBeaconHead ()
99- if err != nil {
100- return 0 , time.Time {}, nil , err
101- }
102112 finalizedEpoch := beaconHead .FinalizedEpoch
103113 if requiredEpoch > finalizedEpoch {
104114 return 0 , time.Time {}, nil , fmt .Errorf ("balances must be reported for EL block %d, waiting until Epoch %d is finalized (currently %d)" , targetBlockNumber , requiredEpoch , finalizedEpoch )
105115 }
106116
107117 return slotNumber , nextSubmissionTime , targetBlockHeader , nil
108118}
109-
110- func FindNextSubmissionTimestamp (latestBlockTimestamp int64 , referenceTimestamp int64 , submissionIntervalInSeconds int64 ) (int64 , error ) {
111- if latestBlockTimestamp == 0 || referenceTimestamp == 0 || submissionIntervalInSeconds == 0 {
112- return 0 , fmt .Errorf ("FindNextSubmissionTimestamp can't use zero values" )
113- }
114-
115- // Calculate the difference between latestBlockTime and the reference timestamp
116- timeDifference := latestBlockTimestamp - referenceTimestamp
117- if timeDifference < 0 {
118- return 0 , fmt .Errorf ("FindNextSubmissionTimestamp referenceTimestamp in the future" )
119- }
120-
121- // Calculate the remainder to find out how far off from a multiple of the interval the current time is
122- remainder := timeDifference % submissionIntervalInSeconds
123-
124- // Subtract the remainder from current time to find the first multiple of the interval in the past
125- submissionTimeRef := latestBlockTimestamp - remainder
126- return submissionTimeRef , nil
127- }
0 commit comments