From 165c4b0af16a05ab4e926b543c4c1602c9f5d0fe Mon Sep 17 00:00:00 2001 From: Jun Song <87601811+syjn99@users.noreply.github.com> Date: Tue, 4 Nov 2025 16:14:47 +0000 Subject: [PATCH] Handle addition overflow in `/eth/v1/beacon/rewards/attestations/{epoch}` (#15970) * Handle addition overflow in `/eth/v1/beacon/rewards/attestations/{epoch}` * Changelog --- beacon-chain/rpc/eth/rewards/handlers.go | 9 +++++++-- beacon-chain/rpc/eth/rewards/handlers_test.go | 13 +++++++++++++ changelog/syjn99-attestation-epoch-overflow.md | 2 ++ 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 changelog/syjn99-attestation-epoch-overflow.md diff --git a/beacon-chain/rpc/eth/rewards/handlers.go b/beacon-chain/rpc/eth/rewards/handlers.go index 56a87c5b6f..1d392196a0 100644 --- a/beacon-chain/rpc/eth/rewards/handlers.go +++ b/beacon-chain/rpc/eth/rewards/handlers.go @@ -209,8 +209,13 @@ func (s *Server) attRewardsState(w http.ResponseWriter, r *http.Request) (state. httputil.HandleError(w, "Attestation rewards are not supported for Phase 0", http.StatusNotFound) return nil, false } - currentEpoch := uint64(slots.ToEpoch(s.TimeFetcher.CurrentSlot())) - if requestedEpoch+1 >= currentEpoch { + currentEpoch := slots.ToEpoch(s.TimeFetcher.CurrentSlot()) + bufferedEpoch, err := primitives.Epoch(requestedEpoch).SafeAdd(1) + if err != nil { + httputil.HandleError(w, "Could not increment epoch: "+err.Error(), http.StatusNotFound) + return nil, false + } + if bufferedEpoch >= currentEpoch { httputil.HandleError(w, "Attestation rewards are available after two epoch transitions to ensure all attestations have a chance of inclusion", http.StatusNotFound) diff --git a/beacon-chain/rpc/eth/rewards/handlers_test.go b/beacon-chain/rpc/eth/rewards/handlers_test.go index 4e596804a8..f0604ffb9a 100644 --- a/beacon-chain/rpc/eth/rewards/handlers_test.go +++ b/beacon-chain/rpc/eth/rewards/handlers_test.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "fmt" + "math" "net/http" "net/http/httptest" "strconv" @@ -747,6 +748,18 @@ func TestAttestationRewards(t *testing.T) { assert.Equal(t, http.StatusNotFound, e.Code) assert.Equal(t, "Attestation rewards are available after two epoch transitions to ensure all attestations have a chance of inclusion", e.Message) }) + t.Run("epoch overflow", func(t *testing.T) { + url := "http://only.the.epoch.number.at.the.end.is.important/" + strconv.FormatUint(math.MaxUint64, 10) + request := httptest.NewRequest("POST", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.AttestationRewards(writer, request) + assert.Equal(t, http.StatusNotFound, writer.Code) + e := &httputil.DefaultJsonError{} + require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e)) + assert.Equal(t, http.StatusNotFound, e.Code) + }) } func TestSyncCommiteeRewards(t *testing.T) { diff --git a/changelog/syjn99-attestation-epoch-overflow.md b/changelog/syjn99-attestation-epoch-overflow.md new file mode 100644 index 0000000000..90f9b08ed3 --- /dev/null +++ b/changelog/syjn99-attestation-epoch-overflow.md @@ -0,0 +1,2 @@ +### Fixed +- Fix #15969: Handle addition overflow in `/eth/v1/beacon/rewards/attestations/{epoch}`.