-
-
Notifications
You must be signed in to change notification settings - Fork 428
Description
Description
We believe there may be a bug in the /eth/v1/beacon/rewards/sync_committee/{block_id} API where it returns the validator's full balance instead of the reward/penalty delta.
We could be wrong in our analysis, so please correct us if we're misunderstanding the expected behavior.
Observed Behavior
When calling the sync committee rewards API on Lodestar v1.38.0, we get values like:
"reward": "32675030525"(~32.6 ETH in gwei)
When calling the same API on Teku or Lighthouse for the same slot/validator:
"reward": "25038"(~25,000 gwei)
The Lodestar value closely matches the validator's balance, while Teku/Lighthouse return what appears to be the actual sync committee reward delta.
Expected Behavior (based on spec)
From the Beacon API spec, the SyncCommitteeRewards schema shows:
reward:
example: "2000"
description: "sync committee reward in gwei for the validator"The example value of 2000 gwei suggests the field should contain the small reward delta, not the full validator balance.
Evidence
We tested against multiple beacon nodes behind a load balancer on Hoodi testnet:
| Client | Version | Reward Value | Interpretation |
|---|---|---|---|
| Lodestar | v1.38.0 | ~32,000,000,000 | Appears to be validator balance |
| Teku | v25.12.0 | ~25,000 | Appears to be reward delta |
| Lighthouse | v8.0.1 | ~25,000 | Appears to be reward delta |
We also compared the Lodestar "reward" value to the validator's actual balance and they match almost exactly (within a few thousand gwei).
Suspected Code Location
In packages/beacon-node/src/chain/rewards/syncCommitteeRewards.ts, the function appears to:
- Initialize a map with validator balances
- Add/subtract
syncParticipantReward - Return the resulting balance value
The final line returns v.val which is the balance after adjustment, rather than the delta:
const rewards = Array.from(balances, ([validatorIndex, v]) => ({validatorIndex, reward: v.val}));Compare to Lighthouse which calculates new_balance - initial_balance to get the delta.
Impact
This caused incorrect APR calculations in our monitoring system when requests were routed to Lodestar nodes.
Environment
- Lodestar version: v1.38.0
- Network: Hoodi testnet
- Also checked latest
unstablebranch - same behavior
Again, we may be misunderstanding something about how this API is supposed to work. Happy to provide more details or test cases if helpful.