mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-09 03:01:19 +00:00
af70677778
* adding in block rewards to represent consensus payload * Update beacon-chain/rpc/eth/validator/handlers_block.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * radek's comments * more review changes * adding more tests for forks * gaz * updating names * gaz * fixing imports * fixing variable name * gaz * fixing test * renaming variables to match data --------- Co-authored-by: Radosław Kapka <rkapka@wp.pl>
125 lines
4.9 KiB
Go
125 lines
4.9 KiB
Go
package rewards
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/altair"
|
|
coreblocks "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/blocks"
|
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/validators"
|
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stategen"
|
|
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
|
|
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
|
|
)
|
|
|
|
// BlockRewardsFetcher is a interface that provides access to reward related responses
|
|
type BlockRewardsFetcher interface {
|
|
GetBlockRewardsData(context.Context, interfaces.ReadOnlySignedBeaconBlock) (*BlockRewards, *http2.DefaultErrorJson)
|
|
GetStateForRewards(context.Context, interfaces.ReadOnlySignedBeaconBlock) (state.BeaconState, *http2.DefaultErrorJson)
|
|
}
|
|
|
|
// BlockRewardService implements BlockRewardsFetcher and can be declared to access the underlying functions
|
|
type BlockRewardService struct {
|
|
Replayer stategen.ReplayerBuilder
|
|
}
|
|
|
|
// GetBlockRewardsData returns the BlockRewards Object which is used for the BlockRewardsResponse and ProduceBlockV3
|
|
func (rs *BlockRewardService) GetBlockRewardsData(ctx context.Context, blk interfaces.ReadOnlySignedBeaconBlock) (*BlockRewards, *http2.DefaultErrorJson) {
|
|
st, httpErr := rs.GetStateForRewards(ctx, blk)
|
|
if httpErr != nil {
|
|
return nil, httpErr
|
|
}
|
|
|
|
proposerIndex := blk.Block().ProposerIndex()
|
|
initBalance, err := st.BalanceAtIndex(proposerIndex)
|
|
if err != nil {
|
|
return nil, &http2.DefaultErrorJson{
|
|
Message: "Could not get proposer's balance: " + err.Error(),
|
|
Code: http.StatusInternalServerError,
|
|
}
|
|
}
|
|
st, err = altair.ProcessAttestationsNoVerifySignature(ctx, st, blk)
|
|
if err != nil {
|
|
return nil, &http2.DefaultErrorJson{
|
|
Message: "Could not get attestation rewards: " + err.Error(),
|
|
Code: http.StatusInternalServerError,
|
|
}
|
|
}
|
|
attBalance, err := st.BalanceAtIndex(proposerIndex)
|
|
if err != nil {
|
|
return nil, &http2.DefaultErrorJson{
|
|
Message: "Could not get proposer's balance: " + err.Error(),
|
|
Code: http.StatusInternalServerError,
|
|
}
|
|
}
|
|
st, err = coreblocks.ProcessAttesterSlashings(ctx, st, blk.Block().Body().AttesterSlashings(), validators.SlashValidator)
|
|
if err != nil {
|
|
return nil, &http2.DefaultErrorJson{
|
|
Message: "Could not get attester slashing rewards: " + err.Error(),
|
|
Code: http.StatusInternalServerError,
|
|
}
|
|
}
|
|
attSlashingsBalance, err := st.BalanceAtIndex(proposerIndex)
|
|
if err != nil {
|
|
return nil, &http2.DefaultErrorJson{
|
|
Message: "Could not get proposer's balance: " + err.Error(),
|
|
Code: http.StatusInternalServerError,
|
|
}
|
|
}
|
|
st, err = coreblocks.ProcessProposerSlashings(ctx, st, blk.Block().Body().ProposerSlashings(), validators.SlashValidator)
|
|
if err != nil {
|
|
return nil, &http2.DefaultErrorJson{
|
|
Message: "Could not get proposer slashing rewards: " + err.Error(),
|
|
Code: http.StatusInternalServerError,
|
|
}
|
|
}
|
|
proposerSlashingsBalance, err := st.BalanceAtIndex(proposerIndex)
|
|
if err != nil {
|
|
return nil, &http2.DefaultErrorJson{
|
|
Message: "Could not get proposer's balance: " + err.Error(),
|
|
Code: http.StatusInternalServerError,
|
|
}
|
|
}
|
|
sa, err := blk.Block().Body().SyncAggregate()
|
|
if err != nil {
|
|
return nil, &http2.DefaultErrorJson{
|
|
Message: "Could not get sync aggregate: " + err.Error(),
|
|
Code: http.StatusInternalServerError,
|
|
}
|
|
}
|
|
var syncCommitteeReward uint64
|
|
_, syncCommitteeReward, err = altair.ProcessSyncAggregate(ctx, st, sa)
|
|
if err != nil {
|
|
return nil, &http2.DefaultErrorJson{
|
|
Message: "Could not get sync aggregate rewards: " + err.Error(),
|
|
Code: http.StatusInternalServerError,
|
|
}
|
|
}
|
|
|
|
return &BlockRewards{
|
|
ProposerIndex: strconv.FormatUint(uint64(proposerIndex), 10),
|
|
Total: strconv.FormatUint(proposerSlashingsBalance-initBalance+syncCommitteeReward, 10),
|
|
Attestations: strconv.FormatUint(attBalance-initBalance, 10),
|
|
SyncAggregate: strconv.FormatUint(syncCommitteeReward, 10),
|
|
ProposerSlashings: strconv.FormatUint(proposerSlashingsBalance-attSlashingsBalance, 10),
|
|
AttesterSlashings: strconv.FormatUint(attSlashingsBalance-attBalance, 10),
|
|
}, nil
|
|
}
|
|
|
|
// GetStateForRewards returns the state replayed up to the block's slot
|
|
func (rs *BlockRewardService) GetStateForRewards(ctx context.Context, blk interfaces.ReadOnlySignedBeaconBlock) (state.BeaconState, *http2.DefaultErrorJson) {
|
|
// We want to run several block processing functions that update the proposer's balance.
|
|
// This will allow us to calculate proposer rewards for each operation (atts, slashings etc).
|
|
// To do this, we replay the state up to the block's slot, but before processing the block.
|
|
st, err := rs.Replayer.ReplayerForSlot(blk.Block().Slot()-1).ReplayToSlot(ctx, blk.Block().Slot())
|
|
if err != nil {
|
|
return nil, &http2.DefaultErrorJson{
|
|
Message: "Could not get state: " + err.Error(),
|
|
Code: http.StatusInternalServerError,
|
|
}
|
|
}
|
|
return st, nil
|
|
}
|