Skip to content

Commit f1e3613

Browse files
authored
Merge pull request #976 from rocket-pool/fix-next-submission-target
Fix next submission target
2 parents d0b79a5 + 1f373b8 commit f1e3613

File tree

3 files changed

+46
-47
lines changed

3 files changed

+46
-47
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
build:
1414
runs-on: ubuntu-latest
1515
steps:
16-
- run: sudo apt install -y gcc-aarch64-linux-gnu libc6-dev-arm64-cross g++-aarch64-linux-gnu
16+
- run: sudo apt update && sudo apt install -y gcc-aarch64-linux-gnu libc6-dev-arm64-cross g++-aarch64-linux-gnu
1717
- uses: actions/checkout@v4
1818
- uses: actions/setup-go@v5
1919
with:

rocketpool/watchtower/submit-network-balances.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,16 @@ func (t *submitNetworkBalances) run(state *state.NetworkState) error {
158158
}
159159
targetBlockNumber := targetBlockHeader.Number.Uint64()
160160

161-
if targetBlockNumber > state.ElBlockNumber {
162-
// No submission needed: target block in the future
161+
if targetBlockNumber > state.ElBlockNumber || targetBlockNumber == lastSubmissionBlock {
162+
if targetBlockNumber > state.ElBlockNumber {
163+
// No submission needed: Target block in the future
164+
t.log.Println("not enough time has passed for the next price/balances submission")
165+
return nil
166+
}
167+
if targetBlockNumber == lastSubmissionBlock {
168+
// No submission needed: Already submitted for this block
169+
t.log.Println("balances have already been submitted for this block")
170+
}
163171
return nil
164172
}
165173

rocketpool/watchtower/utils/utils.go

Lines changed: 35 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -49,34 +49,49 @@ func FindLastBlockWithExecutionPayload(bc beacon.Client, slotNumber uint64) (bea
4949
}
5050

5151
func 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

Comments
 (0)