mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
Deneb: Produce Block V3 - adding consensus block value (#12948)
* 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>
This commit is contained in:
@@ -4,6 +4,7 @@ const (
|
|||||||
VersionHeader = "Eth-Consensus-Version"
|
VersionHeader = "Eth-Consensus-Version"
|
||||||
ExecutionPayloadBlindedHeader = "Eth-Execution-Payload-Blinded"
|
ExecutionPayloadBlindedHeader = "Eth-Execution-Payload-Blinded"
|
||||||
ExecutionPayloadValueHeader = "Eth-Execution-Payload-Value"
|
ExecutionPayloadValueHeader = "Eth-Execution-Payload-Value"
|
||||||
|
ConsensusBlockValueHeader = "Eth-Consensus-Block-Value"
|
||||||
JsonMediaType = "application/json"
|
JsonMediaType = "application/json"
|
||||||
OctetStreamMediaType = "application/octet-stream"
|
OctetStreamMediaType = "application/octet-stream"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ go_library(
|
|||||||
srcs = [
|
srcs = [
|
||||||
"handlers.go",
|
"handlers.go",
|
||||||
"server.go",
|
"server.go",
|
||||||
|
"service.go",
|
||||||
"structs.go",
|
"structs.go",
|
||||||
],
|
],
|
||||||
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/rewards",
|
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/rewards",
|
||||||
@@ -21,11 +22,13 @@ go_library(
|
|||||||
"//beacon-chain/state/stategen:go_default_library",
|
"//beacon-chain/state/stategen:go_default_library",
|
||||||
"//config/fieldparams:go_default_library",
|
"//config/fieldparams:go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
|
"//consensus-types/interfaces:go_default_library",
|
||||||
"//consensus-types/primitives:go_default_library",
|
"//consensus-types/primitives:go_default_library",
|
||||||
"//network/http:go_default_library",
|
"//network/http:go_default_library",
|
||||||
"//runtime/version:go_default_library",
|
"//runtime/version:go_default_library",
|
||||||
"//time/slots:go_default_library",
|
"//time/slots:go_default_library",
|
||||||
"@com_github_wealdtech_go_bytesutil//:go_default_library",
|
"@com_github_wealdtech_go_bytesutil//:go_default_library",
|
||||||
|
"@io_opencensus_go//trace:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -54,6 +57,7 @@ go_test(
|
|||||||
"//testing/assert:go_default_library",
|
"//testing/assert:go_default_library",
|
||||||
"//testing/require:go_default_library",
|
"//testing/require:go_default_library",
|
||||||
"//testing/util:go_default_library",
|
"//testing/util:go_default_library",
|
||||||
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,9 +8,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/altair"
|
"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/epoch/precompute"
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/epoch/precompute"
|
||||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/validators"
|
|
||||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
||||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||||
@@ -20,10 +18,13 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/v4/runtime/version"
|
"github.com/prysmaticlabs/prysm/v4/runtime/version"
|
||||||
"github.com/prysmaticlabs/prysm/v4/time/slots"
|
"github.com/prysmaticlabs/prysm/v4/time/slots"
|
||||||
"github.com/wealdtech/go-bytesutil"
|
"github.com/wealdtech/go-bytesutil"
|
||||||
|
"go.opencensus.io/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BlockRewards is an HTTP handler for Beacon API getBlockRewards.
|
// BlockRewards is an HTTP handler for Beacon API getBlockRewards.
|
||||||
func (s *Server) BlockRewards(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) BlockRewards(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx, span := trace.StartSpan(r.Context(), "beacon.BlockRewards")
|
||||||
|
defer span.End()
|
||||||
segments := strings.Split(r.URL.Path, "/")
|
segments := strings.Split(r.URL.Path, "/")
|
||||||
blockId := segments[len(segments)-1]
|
blockId := segments[len(segments)-1]
|
||||||
|
|
||||||
@@ -36,63 +37,6 @@ func (s *Server) BlockRewards(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 := s.ReplayerBuilder.ReplayerForSlot(blk.Block().Slot()-1).ReplayToSlot(r.Context(), blk.Block().Slot())
|
|
||||||
if err != nil {
|
|
||||||
http2.HandleError(w, "Could not get state: "+err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
proposerIndex := blk.Block().ProposerIndex()
|
|
||||||
initBalance, err := st.BalanceAtIndex(proposerIndex)
|
|
||||||
if err != nil {
|
|
||||||
http2.HandleError(w, "Could not get proposer's balance: "+err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
st, err = altair.ProcessAttestationsNoVerifySignature(r.Context(), st, blk)
|
|
||||||
if err != nil {
|
|
||||||
http2.HandleError(w, "Could not get attestation rewards"+err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
attBalance, err := st.BalanceAtIndex(proposerIndex)
|
|
||||||
if err != nil {
|
|
||||||
http2.HandleError(w, "Could not get proposer's balance: "+err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
st, err = coreblocks.ProcessAttesterSlashings(r.Context(), st, blk.Block().Body().AttesterSlashings(), validators.SlashValidator)
|
|
||||||
if err != nil {
|
|
||||||
http2.HandleError(w, "Could not get attester slashing rewards: "+err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
attSlashingsBalance, err := st.BalanceAtIndex(proposerIndex)
|
|
||||||
if err != nil {
|
|
||||||
http2.HandleError(w, "Could not get proposer's balance: "+err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
st, err = coreblocks.ProcessProposerSlashings(r.Context(), st, blk.Block().Body().ProposerSlashings(), validators.SlashValidator)
|
|
||||||
if err != nil {
|
|
||||||
http2.HandleError(w, "Could not get proposer slashing rewards"+err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
proposerSlashingsBalance, err := st.BalanceAtIndex(proposerIndex)
|
|
||||||
if err != nil {
|
|
||||||
http2.HandleError(w, "Could not get proposer's balance: "+err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
sa, err := blk.Block().Body().SyncAggregate()
|
|
||||||
if err != nil {
|
|
||||||
http2.HandleError(w, "Could not get sync aggregate: "+err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var syncCommitteeReward uint64
|
|
||||||
_, syncCommitteeReward, err = altair.ProcessSyncAggregate(r.Context(), st, sa)
|
|
||||||
if err != nil {
|
|
||||||
http2.HandleError(w, "Could not get sync aggregate rewards: "+err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
optimistic, err := s.OptimisticModeFetcher.IsOptimistic(r.Context())
|
optimistic, err := s.OptimisticModeFetcher.IsOptimistic(r.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http2.HandleError(w, "Could not get optimistic mode info: "+err.Error(), http.StatusInternalServerError)
|
http2.HandleError(w, "Could not get optimistic mode info: "+err.Error(), http.StatusInternalServerError)
|
||||||
@@ -103,18 +47,15 @@ func (s *Server) BlockRewards(w http.ResponseWriter, r *http.Request) {
|
|||||||
http2.HandleError(w, "Could not get block root: "+err.Error(), http.StatusInternalServerError)
|
http2.HandleError(w, "Could not get block root: "+err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
blockRewards, httpError := s.BlockRewardFetcher.GetBlockRewardsData(ctx, blk)
|
||||||
|
if httpError != nil {
|
||||||
|
http2.WriteError(w, httpError)
|
||||||
|
return
|
||||||
|
}
|
||||||
response := &BlockRewardsResponse{
|
response := &BlockRewardsResponse{
|
||||||
Data: BlockRewards{
|
Data: 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),
|
|
||||||
},
|
|
||||||
ExecutionOptimistic: optimistic,
|
ExecutionOptimistic: optimistic,
|
||||||
Finalized: s.FinalizationFetcher.IsFinalized(r.Context(), blkRoot),
|
Finalized: s.FinalizationFetcher.IsFinalized(ctx, blkRoot),
|
||||||
}
|
}
|
||||||
http2.WriteJson(w, response)
|
http2.WriteJson(w, response)
|
||||||
}
|
}
|
||||||
@@ -165,6 +106,8 @@ func (s *Server) AttestationRewards(w http.ResponseWriter, r *http.Request) {
|
|||||||
// SyncCommitteeRewards retrieves rewards info for sync committee members specified by array of public keys or validator index.
|
// SyncCommitteeRewards retrieves rewards info for sync committee members specified by array of public keys or validator index.
|
||||||
// If no array is provided, return reward info for every committee member.
|
// If no array is provided, return reward info for every committee member.
|
||||||
func (s *Server) SyncCommitteeRewards(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) SyncCommitteeRewards(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx, span := trace.StartSpan(r.Context(), "beacon.SyncCommitteeRewards")
|
||||||
|
defer span.End()
|
||||||
segments := strings.Split(r.URL.Path, "/")
|
segments := strings.Split(r.URL.Path, "/")
|
||||||
blockId := segments[len(segments)-1]
|
blockId := segments[len(segments)-1]
|
||||||
|
|
||||||
@@ -176,9 +119,10 @@ func (s *Server) SyncCommitteeRewards(w http.ResponseWriter, r *http.Request) {
|
|||||||
http2.HandleError(w, "Sync committee rewards are not supported for Phase 0", http.StatusBadRequest)
|
http2.HandleError(w, "Sync committee rewards are not supported for Phase 0", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
st, err := s.ReplayerBuilder.ReplayerForSlot(blk.Block().Slot()-1).ReplayToSlot(r.Context(), blk.Block().Slot())
|
|
||||||
if err != nil {
|
st, httpErr := s.BlockRewardFetcher.GetStateForRewards(ctx, blk)
|
||||||
http2.HandleError(w, "Could not get state: "+err.Error(), http.StatusInternalServerError)
|
if httpErr != nil {
|
||||||
|
http2.WriteError(w, httpErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sa, err := blk.Block().Body().SyncAggregate()
|
sa, err := blk.Block().Body().SyncAggregate()
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
"github.com/prysmaticlabs/go-bitfield"
|
||||||
mock "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
|
mock "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
|
||||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/altair"
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/altair"
|
||||||
@@ -34,12 +35,42 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/v4/testing/util"
|
"github.com/prysmaticlabs/prysm/v4/testing/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBlockRewards(t *testing.T) {
|
func BlockRewardTestSetup(t *testing.T, forkName string) (state.BeaconState, interfaces.SignedBeaconBlock, error) {
|
||||||
helpers.ClearCache()
|
helpers.ClearCache()
|
||||||
|
var sbb interfaces.SignedBeaconBlock
|
||||||
|
var st state.BeaconState
|
||||||
|
var err error
|
||||||
|
switch forkName {
|
||||||
|
case "phase0":
|
||||||
|
return nil, nil, errors.New("phase0 not supported")
|
||||||
|
case "altair":
|
||||||
|
st, err = util.NewBeaconStateAltair()
|
||||||
|
require.NoError(t, err)
|
||||||
|
b := util.HydrateSignedBeaconBlockAltair(util.NewBeaconBlockAltair())
|
||||||
|
sbb, err = blocks.NewSignedBeaconBlock(b)
|
||||||
|
require.NoError(t, err)
|
||||||
|
case "bellatrix":
|
||||||
|
st, err = util.NewBeaconStateBellatrix()
|
||||||
|
require.NoError(t, err)
|
||||||
|
b := util.HydrateSignedBeaconBlockBellatrix(util.NewBeaconBlockBellatrix())
|
||||||
|
sbb, err = blocks.NewSignedBeaconBlock(b)
|
||||||
|
require.NoError(t, err)
|
||||||
|
case "capella":
|
||||||
|
st, err = util.NewBeaconStateCapella()
|
||||||
|
require.NoError(t, err)
|
||||||
|
b := util.HydrateSignedBeaconBlockCapella(util.NewBeaconBlockCapella())
|
||||||
|
sbb, err = blocks.NewSignedBeaconBlock(b)
|
||||||
|
require.NoError(t, err)
|
||||||
|
case "deneb":
|
||||||
|
st, err = util.NewBeaconStateDeneb()
|
||||||
|
require.NoError(t, err)
|
||||||
|
b := util.HydrateSignedBeaconBlockDeneb(util.NewBeaconBlockDeneb())
|
||||||
|
sbb, err = blocks.NewSignedBeaconBlock(b)
|
||||||
|
require.NoError(t, err)
|
||||||
|
default:
|
||||||
|
return nil, nil, errors.New("fork is not supported")
|
||||||
|
}
|
||||||
valCount := 64
|
valCount := 64
|
||||||
|
|
||||||
st, err := util.NewBeaconStateCapella()
|
|
||||||
require.NoError(t, st.SetSlot(1))
|
require.NoError(t, st.SetSlot(1))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
validators := make([]*eth.Validator, 0, valCount)
|
validators := make([]*eth.Validator, 0, valCount)
|
||||||
@@ -68,11 +99,10 @@ func TestBlockRewards(t *testing.T) {
|
|||||||
bRoots[0] = slot0bRoot
|
bRoots[0] = slot0bRoot
|
||||||
require.NoError(t, st.SetBlockRoots(bRoots))
|
require.NoError(t, st.SetBlockRoots(bRoots))
|
||||||
|
|
||||||
b := util.HydrateSignedBeaconBlockCapella(util.NewBeaconBlockCapella())
|
sbb.SetSlot(2)
|
||||||
b.Block.Slot = 2
|
|
||||||
// we have to set the proposer index to the value that will be randomly chosen (fortunately it's deterministic)
|
// we have to set the proposer index to the value that will be randomly chosen (fortunately it's deterministic)
|
||||||
b.Block.ProposerIndex = 12
|
sbb.SetProposerIndex(12)
|
||||||
b.Block.Body.Attestations = []*eth.Attestation{
|
sbb.SetAttestations([]*eth.Attestation{
|
||||||
{
|
{
|
||||||
AggregationBits: bitfield.Bitlist{0b00000111},
|
AggregationBits: bitfield.Bitlist{0b00000111},
|
||||||
Data: util.HydrateAttestationData(ð.AttestationData{}),
|
Data: util.HydrateAttestationData(ð.AttestationData{}),
|
||||||
@@ -83,7 +113,8 @@ func TestBlockRewards(t *testing.T) {
|
|||||||
Data: util.HydrateAttestationData(ð.AttestationData{}),
|
Data: util.HydrateAttestationData(ð.AttestationData{}),
|
||||||
Signature: make([]byte, fieldparams.BLSSignatureLength),
|
Signature: make([]byte, fieldparams.BLSSignatureLength),
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
|
|
||||||
attData1 := util.HydrateAttestationData(ð.AttestationData{BeaconBlockRoot: bytesutil.PadTo([]byte("root1"), 32)})
|
attData1 := util.HydrateAttestationData(ð.AttestationData{BeaconBlockRoot: bytesutil.PadTo([]byte("root1"), 32)})
|
||||||
attData2 := util.HydrateAttestationData(ð.AttestationData{BeaconBlockRoot: bytesutil.PadTo([]byte("root2"), 32)})
|
attData2 := util.HydrateAttestationData(ð.AttestationData{BeaconBlockRoot: bytesutil.PadTo([]byte("root2"), 32)})
|
||||||
domain, err := signing.Domain(st.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorsRoot())
|
domain, err := signing.Domain(st.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorsRoot())
|
||||||
@@ -92,7 +123,7 @@ func TestBlockRewards(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
sigRoot2, err := signing.ComputeSigningRoot(attData2, domain)
|
sigRoot2, err := signing.ComputeSigningRoot(attData2, domain)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
b.Block.Body.AttesterSlashings = []*eth.AttesterSlashing{
|
sbb.SetAttesterSlashings([]*eth.AttesterSlashing{
|
||||||
{
|
{
|
||||||
Attestation_1: ð.IndexedAttestation{
|
Attestation_1: ð.IndexedAttestation{
|
||||||
AttestingIndices: []uint64{0},
|
AttestingIndices: []uint64{0},
|
||||||
@@ -105,7 +136,7 @@ func TestBlockRewards(t *testing.T) {
|
|||||||
Signature: secretKeys[0].Sign(sigRoot2[:]).Marshal(),
|
Signature: secretKeys[0].Sign(sigRoot2[:]).Marshal(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
header1 := ð.BeaconBlockHeader{
|
header1 := ð.BeaconBlockHeader{
|
||||||
Slot: 0,
|
Slot: 0,
|
||||||
ProposerIndex: 1,
|
ProposerIndex: 1,
|
||||||
@@ -126,7 +157,7 @@ func TestBlockRewards(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
sigRoot2, err = signing.ComputeSigningRoot(header2, domain)
|
sigRoot2, err = signing.ComputeSigningRoot(header2, domain)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
b.Block.Body.ProposerSlashings = []*eth.ProposerSlashing{
|
sbb.SetProposerSlashings([]*eth.ProposerSlashing{
|
||||||
{
|
{
|
||||||
Header_1: ð.SignedBeaconBlockHeader{
|
Header_1: ð.SignedBeaconBlockHeader{
|
||||||
Header: header1,
|
Header: header1,
|
||||||
@@ -137,7 +168,7 @@ func TestBlockRewards(t *testing.T) {
|
|||||||
Signature: secretKeys[1].Sign(sigRoot2[:]).Marshal(),
|
Signature: secretKeys[1].Sign(sigRoot2[:]).Marshal(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
scBits := bitfield.NewBitvector512()
|
scBits := bitfield.NewBitvector512()
|
||||||
scBits.SetBitAt(10, true)
|
scBits.SetBitAt(10, true)
|
||||||
scBits.SetBitAt(100, true)
|
scBits.SetBitAt(100, true)
|
||||||
@@ -153,24 +184,51 @@ func TestBlockRewards(t *testing.T) {
|
|||||||
sig2, err := blst.SignatureFromBytes(secretKeys[19].Sign(r[:]).Marshal())
|
sig2, err := blst.SignatureFromBytes(secretKeys[19].Sign(r[:]).Marshal())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
aggSig := bls.AggregateSignatures([]bls.Signature{sig1, sig2}).Marshal()
|
aggSig := bls.AggregateSignatures([]bls.Signature{sig1, sig2}).Marshal()
|
||||||
b.Block.Body.SyncAggregate = ð.SyncAggregate{SyncCommitteeBits: scBits, SyncCommitteeSignature: aggSig}
|
err = sbb.SetSyncAggregate(ð.SyncAggregate{SyncCommitteeBits: scBits, SyncCommitteeSignature: aggSig})
|
||||||
|
|
||||||
sbb, err := blocks.NewSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
return st, sbb, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBlockRewards(t *testing.T) {
|
||||||
phase0block, err := blocks.NewSignedBeaconBlock(util.NewBeaconBlock())
|
phase0block, err := blocks.NewSignedBeaconBlock(util.NewBeaconBlock())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
mockChainService := &mock.ChainService{Optimistic: true}
|
t.Run("phase 0", func(t *testing.T) {
|
||||||
s := &Server{
|
mockChainService := &mock.ChainService{Optimistic: true}
|
||||||
Blocker: &testutil.MockBlocker{SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{
|
s := &Server{
|
||||||
0: phase0block,
|
Blocker: &testutil.MockBlocker{SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{
|
||||||
2: sbb,
|
0: phase0block,
|
||||||
}},
|
}},
|
||||||
OptimisticModeFetcher: mockChainService,
|
OptimisticModeFetcher: mockChainService,
|
||||||
FinalizationFetcher: mockChainService,
|
FinalizationFetcher: mockChainService,
|
||||||
ReplayerBuilder: mockstategen.NewMockReplayerBuilder(mockstategen.WithMockState(st)),
|
}
|
||||||
}
|
url := "http://only.the.slot.number.at.the.end.is.important/0"
|
||||||
|
request := httptest.NewRequest("GET", url, nil)
|
||||||
|
writer := httptest.NewRecorder()
|
||||||
|
writer.Body = &bytes.Buffer{}
|
||||||
|
|
||||||
|
s.BlockRewards(writer, request)
|
||||||
|
assert.Equal(t, http.StatusBadRequest, writer.Code)
|
||||||
|
e := &http2.DefaultErrorJson{}
|
||||||
|
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
|
||||||
|
assert.Equal(t, http.StatusBadRequest, e.Code)
|
||||||
|
assert.Equal(t, "Block rewards are not supported for Phase 0 blocks", e.Message)
|
||||||
|
})
|
||||||
|
t.Run("altair", func(t *testing.T) {
|
||||||
|
st, sbb, err := BlockRewardTestSetup(t, "altair")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
mockChainService := &mock.ChainService{Optimistic: true}
|
||||||
|
s := &Server{
|
||||||
|
Blocker: &testutil.MockBlocker{SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{
|
||||||
|
0: phase0block,
|
||||||
|
2: sbb,
|
||||||
|
}},
|
||||||
|
OptimisticModeFetcher: mockChainService,
|
||||||
|
FinalizationFetcher: mockChainService,
|
||||||
|
BlockRewardFetcher: &BlockRewardService{Replayer: mockstategen.NewMockReplayerBuilder(mockstategen.WithMockState(st))},
|
||||||
|
}
|
||||||
|
|
||||||
t.Run("ok", func(t *testing.T) {
|
|
||||||
url := "http://only.the.slot.number.at.the.end.is.important/2"
|
url := "http://only.the.slot.number.at.the.end.is.important/2"
|
||||||
request := httptest.NewRequest("GET", url, nil)
|
request := httptest.NewRequest("GET", url, nil)
|
||||||
writer := httptest.NewRecorder()
|
writer := httptest.NewRecorder()
|
||||||
@@ -189,18 +247,104 @@ func TestBlockRewards(t *testing.T) {
|
|||||||
assert.Equal(t, true, resp.ExecutionOptimistic)
|
assert.Equal(t, true, resp.ExecutionOptimistic)
|
||||||
assert.Equal(t, false, resp.Finalized)
|
assert.Equal(t, false, resp.Finalized)
|
||||||
})
|
})
|
||||||
t.Run("phase 0", func(t *testing.T) {
|
t.Run("bellatrix", func(t *testing.T) {
|
||||||
url := "http://only.the.slot.number.at.the.end.is.important/0"
|
st, sbb, err := BlockRewardTestSetup(t, "bellatrix")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
mockChainService := &mock.ChainService{Optimistic: true}
|
||||||
|
s := &Server{
|
||||||
|
Blocker: &testutil.MockBlocker{SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{
|
||||||
|
0: phase0block,
|
||||||
|
2: sbb,
|
||||||
|
}},
|
||||||
|
OptimisticModeFetcher: mockChainService,
|
||||||
|
FinalizationFetcher: mockChainService,
|
||||||
|
BlockRewardFetcher: &BlockRewardService{Replayer: mockstategen.NewMockReplayerBuilder(mockstategen.WithMockState(st))},
|
||||||
|
}
|
||||||
|
|
||||||
|
url := "http://only.the.slot.number.at.the.end.is.important/2"
|
||||||
request := httptest.NewRequest("GET", url, nil)
|
request := httptest.NewRequest("GET", url, nil)
|
||||||
writer := httptest.NewRecorder()
|
writer := httptest.NewRecorder()
|
||||||
writer.Body = &bytes.Buffer{}
|
writer.Body = &bytes.Buffer{}
|
||||||
|
|
||||||
s.BlockRewards(writer, request)
|
s.BlockRewards(writer, request)
|
||||||
assert.Equal(t, http.StatusBadRequest, writer.Code)
|
assert.Equal(t, http.StatusOK, writer.Code)
|
||||||
e := &http2.DefaultErrorJson{}
|
resp := &BlockRewardsResponse{}
|
||||||
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
|
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
|
||||||
assert.Equal(t, http.StatusBadRequest, e.Code)
|
assert.Equal(t, "12", resp.Data.ProposerIndex)
|
||||||
assert.Equal(t, "Block rewards are not supported for Phase 0 blocks", e.Message)
|
assert.Equal(t, "125089490", resp.Data.Total)
|
||||||
|
assert.Equal(t, "89442", resp.Data.Attestations)
|
||||||
|
assert.Equal(t, "48", resp.Data.SyncAggregate)
|
||||||
|
assert.Equal(t, "62500000", resp.Data.AttesterSlashings)
|
||||||
|
assert.Equal(t, "62500000", resp.Data.ProposerSlashings)
|
||||||
|
assert.Equal(t, true, resp.ExecutionOptimistic)
|
||||||
|
assert.Equal(t, false, resp.Finalized)
|
||||||
|
})
|
||||||
|
t.Run("capella", func(t *testing.T) {
|
||||||
|
st, sbb, err := BlockRewardTestSetup(t, "capella")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
mockChainService := &mock.ChainService{Optimistic: true}
|
||||||
|
s := &Server{
|
||||||
|
Blocker: &testutil.MockBlocker{SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{
|
||||||
|
0: phase0block,
|
||||||
|
2: sbb,
|
||||||
|
}},
|
||||||
|
OptimisticModeFetcher: mockChainService,
|
||||||
|
FinalizationFetcher: mockChainService,
|
||||||
|
BlockRewardFetcher: &BlockRewardService{Replayer: mockstategen.NewMockReplayerBuilder(mockstategen.WithMockState(st))},
|
||||||
|
}
|
||||||
|
|
||||||
|
url := "http://only.the.slot.number.at.the.end.is.important/2"
|
||||||
|
request := httptest.NewRequest("GET", url, nil)
|
||||||
|
writer := httptest.NewRecorder()
|
||||||
|
writer.Body = &bytes.Buffer{}
|
||||||
|
|
||||||
|
s.BlockRewards(writer, request)
|
||||||
|
assert.Equal(t, http.StatusOK, writer.Code)
|
||||||
|
resp := &BlockRewardsResponse{}
|
||||||
|
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
|
||||||
|
assert.Equal(t, "12", resp.Data.ProposerIndex)
|
||||||
|
assert.Equal(t, "125089490", resp.Data.Total)
|
||||||
|
assert.Equal(t, "89442", resp.Data.Attestations)
|
||||||
|
assert.Equal(t, "48", resp.Data.SyncAggregate)
|
||||||
|
assert.Equal(t, "62500000", resp.Data.AttesterSlashings)
|
||||||
|
assert.Equal(t, "62500000", resp.Data.ProposerSlashings)
|
||||||
|
assert.Equal(t, true, resp.ExecutionOptimistic)
|
||||||
|
assert.Equal(t, false, resp.Finalized)
|
||||||
|
})
|
||||||
|
t.Run("deneb", func(t *testing.T) {
|
||||||
|
st, sbb, err := BlockRewardTestSetup(t, "deneb")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
mockChainService := &mock.ChainService{Optimistic: true}
|
||||||
|
s := &Server{
|
||||||
|
Blocker: &testutil.MockBlocker{SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{
|
||||||
|
0: phase0block,
|
||||||
|
2: sbb,
|
||||||
|
}},
|
||||||
|
OptimisticModeFetcher: mockChainService,
|
||||||
|
FinalizationFetcher: mockChainService,
|
||||||
|
BlockRewardFetcher: &BlockRewardService{Replayer: mockstategen.NewMockReplayerBuilder(mockstategen.WithMockState(st))},
|
||||||
|
}
|
||||||
|
|
||||||
|
url := "http://only.the.slot.number.at.the.end.is.important/2"
|
||||||
|
request := httptest.NewRequest("GET", url, nil)
|
||||||
|
writer := httptest.NewRecorder()
|
||||||
|
writer.Body = &bytes.Buffer{}
|
||||||
|
|
||||||
|
s.BlockRewards(writer, request)
|
||||||
|
assert.Equal(t, http.StatusOK, writer.Code)
|
||||||
|
resp := &BlockRewardsResponse{}
|
||||||
|
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
|
||||||
|
assert.Equal(t, "12", resp.Data.ProposerIndex)
|
||||||
|
assert.Equal(t, "125089490", resp.Data.Total)
|
||||||
|
assert.Equal(t, "89442", resp.Data.Attestations)
|
||||||
|
assert.Equal(t, "48", resp.Data.SyncAggregate)
|
||||||
|
assert.Equal(t, "62500000", resp.Data.AttesterSlashings)
|
||||||
|
assert.Equal(t, "62500000", resp.Data.ProposerSlashings)
|
||||||
|
assert.Equal(t, true, resp.ExecutionOptimistic)
|
||||||
|
assert.Equal(t, false, resp.Finalized)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -560,7 +704,7 @@ func TestSyncCommiteeRewards(t *testing.T) {
|
|||||||
}},
|
}},
|
||||||
OptimisticModeFetcher: mockChainService,
|
OptimisticModeFetcher: mockChainService,
|
||||||
FinalizationFetcher: mockChainService,
|
FinalizationFetcher: mockChainService,
|
||||||
ReplayerBuilder: mockstategen.NewMockReplayerBuilder(mockstategen.WithMockState(st)),
|
BlockRewardFetcher: &BlockRewardService{Replayer: mockstategen.NewMockReplayerBuilder(mockstategen.WithMockState(st))},
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("ok - filtered vals", func(t *testing.T) {
|
t.Run("ok - filtered vals", func(t *testing.T) {
|
||||||
|
|||||||
@@ -3,15 +3,14 @@ package rewards
|
|||||||
import (
|
import (
|
||||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain"
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain"
|
||||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
|
||||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stategen"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
Blocker lookup.Blocker
|
Blocker lookup.Blocker
|
||||||
OptimisticModeFetcher blockchain.OptimisticModeFetcher
|
OptimisticModeFetcher blockchain.OptimisticModeFetcher
|
||||||
FinalizationFetcher blockchain.FinalizationFetcher
|
FinalizationFetcher blockchain.FinalizationFetcher
|
||||||
ReplayerBuilder stategen.ReplayerBuilder
|
|
||||||
TimeFetcher blockchain.TimeFetcher
|
TimeFetcher blockchain.TimeFetcher
|
||||||
Stater lookup.Stater
|
Stater lookup.Stater
|
||||||
HeadFetcher blockchain.HeadFetcher
|
HeadFetcher blockchain.HeadFetcher
|
||||||
|
BlockRewardFetcher BlockRewardsFetcher
|
||||||
}
|
}
|
||||||
|
|||||||
124
beacon-chain/rpc/eth/rewards/service.go
Normal file
124
beacon-chain/rpc/eth/rewards/service.go
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package rewards
|
package rewards
|
||||||
|
|
||||||
type BlockRewardsResponse struct {
|
type BlockRewardsResponse struct {
|
||||||
Data BlockRewards `json:"data"`
|
Data *BlockRewards `json:"data"`
|
||||||
ExecutionOptimistic bool `json:"execution_optimistic"`
|
ExecutionOptimistic bool `json:"execution_optimistic"`
|
||||||
Finalized bool `json:"finalized"`
|
Finalized bool `json:"finalized"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type BlockRewards struct {
|
type BlockRewards struct {
|
||||||
|
|||||||
14
beacon-chain/rpc/eth/rewards/testing/BUILD.bazel
Normal file
14
beacon-chain/rpc/eth/rewards/testing/BUILD.bazel
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
load("@prysm//tools/go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = ["mock.go"],
|
||||||
|
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/rewards/testing",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//beacon-chain/rpc/eth/rewards:go_default_library",
|
||||||
|
"//beacon-chain/state:go_default_library",
|
||||||
|
"//consensus-types/interfaces:go_default_library",
|
||||||
|
"//network/http:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
30
beacon-chain/rpc/eth/rewards/testing/mock.go
Normal file
30
beacon-chain/rpc/eth/rewards/testing/mock.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/rewards"
|
||||||
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||||
|
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
|
||||||
|
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MockBlockRewardFetcher struct {
|
||||||
|
Rewards *rewards.BlockRewards
|
||||||
|
Error *http2.DefaultErrorJson
|
||||||
|
State state.BeaconState
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockBlockRewardFetcher) GetBlockRewardsData(_ context.Context, _ interfaces.ReadOnlySignedBeaconBlock) (*rewards.BlockRewards, *http2.DefaultErrorJson) {
|
||||||
|
if m.Error != nil {
|
||||||
|
return nil, m.Error
|
||||||
|
}
|
||||||
|
return m.Rewards, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockBlockRewardFetcher) GetStateForRewards(_ context.Context, _ interfaces.ReadOnlySignedBeaconBlock) (state.BeaconState, *http2.DefaultErrorJson) {
|
||||||
|
if m.Error != nil {
|
||||||
|
return nil, m.Error
|
||||||
|
}
|
||||||
|
return m.State, nil
|
||||||
|
}
|
||||||
@@ -162,7 +162,7 @@ const (
|
|||||||
}`
|
}`
|
||||||
AltairBlock = `{
|
AltairBlock = `{
|
||||||
"message": {
|
"message": {
|
||||||
"slot": "1",
|
"slot": "2",
|
||||||
"proposer_index": "1",
|
"proposer_index": "1",
|
||||||
"parent_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
"parent_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
||||||
"state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
"state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
||||||
@@ -204,7 +204,7 @@ const (
|
|||||||
"attesting_indices": [
|
"attesting_indices": [
|
||||||
"1"
|
"1"
|
||||||
],
|
],
|
||||||
"signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505",
|
"signature": "0xabb0124c7574f281a293f4185cad3cb22681d520917ce46665243eacb051000d8bacf75e1451870ca6b3b9e6c9d41a7b02ead2685a84188a4fafd3825daf6a989625d719ccd2d83a40101f4a453fca62878c890eca622363f9ddb8f367a91e84",
|
||||||
"data": {
|
"data": {
|
||||||
"slot": "1",
|
"slot": "1",
|
||||||
"index": "1",
|
"index": "1",
|
||||||
@@ -223,18 +223,18 @@ const (
|
|||||||
"attesting_indices": [
|
"attesting_indices": [
|
||||||
"1"
|
"1"
|
||||||
],
|
],
|
||||||
"signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505",
|
"signature": "0xabb0124c7574f281a293f4185cad3cb22681d520917ce46665243eacb051000d8bacf75e1451870ca6b3b9e6c9d41a7b02ead2685a84188a4fafd3825daf6a989625d719ccd2d83a40101f4a453fca62878c890eca622363f9ddb8f367a91e84",
|
||||||
"data": {
|
"data": {
|
||||||
"slot": "1",
|
"slot": "1",
|
||||||
"index": "1",
|
"index": "1",
|
||||||
"beacon_block_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
"beacon_block_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
||||||
"source": {
|
"source": {
|
||||||
"epoch": "1",
|
"epoch": "1",
|
||||||
"root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
"root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f3"
|
||||||
},
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"epoch": "1",
|
"epoch": "1",
|
||||||
"root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
"root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -242,18 +242,18 @@ const (
|
|||||||
],
|
],
|
||||||
"attestations": [
|
"attestations": [
|
||||||
{
|
{
|
||||||
"aggregation_bits": "0xffffffffffffffffffffffffffffffffff3f",
|
"aggregation_bits": "0x07",
|
||||||
"signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505",
|
"signature": "0xabb0124c7574f281a293f4185cad3cb22681d520917ce46665243eacb051000d8bacf75e1451870ca6b3b9e6c9d41a7b02ead2685a84188a4fafd3825daf6a989625d719ccd2d83a40101f4a453fca62878c890eca622363f9ddb8f367a91e84",
|
||||||
"data": {
|
"data": {
|
||||||
"slot": "1",
|
"slot": "0",
|
||||||
"index": "1",
|
"index": "0",
|
||||||
"beacon_block_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
"beacon_block_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
||||||
"source": {
|
"source": {
|
||||||
"epoch": "1",
|
"epoch": "1",
|
||||||
"root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
"root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
||||||
},
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"epoch": "1",
|
"epoch": "0",
|
||||||
"root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
"root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ go_library(
|
|||||||
"//beacon-chain/p2p:go_default_library",
|
"//beacon-chain/p2p:go_default_library",
|
||||||
"//beacon-chain/rpc/core:go_default_library",
|
"//beacon-chain/rpc/core:go_default_library",
|
||||||
"//beacon-chain/rpc/eth/helpers:go_default_library",
|
"//beacon-chain/rpc/eth/helpers:go_default_library",
|
||||||
|
"//beacon-chain/rpc/eth/rewards:go_default_library",
|
||||||
"//beacon-chain/rpc/eth/shared:go_default_library",
|
"//beacon-chain/rpc/eth/shared:go_default_library",
|
||||||
"//beacon-chain/rpc/lookup:go_default_library",
|
"//beacon-chain/rpc/lookup:go_default_library",
|
||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
@@ -33,6 +34,8 @@ go_library(
|
|||||||
"//config/fieldparams:go_default_library",
|
"//config/fieldparams:go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
"//consensus-types:go_default_library",
|
"//consensus-types:go_default_library",
|
||||||
|
"//consensus-types/blocks:go_default_library",
|
||||||
|
"//consensus-types/interfaces:go_default_library",
|
||||||
"//consensus-types/primitives:go_default_library",
|
"//consensus-types/primitives:go_default_library",
|
||||||
"//consensus-types/validator:go_default_library",
|
"//consensus-types/validator:go_default_library",
|
||||||
"//encoding/bytesutil:go_default_library",
|
"//encoding/bytesutil:go_default_library",
|
||||||
@@ -75,6 +78,8 @@ go_test(
|
|||||||
"//beacon-chain/operations/synccommittee:go_default_library",
|
"//beacon-chain/operations/synccommittee:go_default_library",
|
||||||
"//beacon-chain/p2p/testing:go_default_library",
|
"//beacon-chain/p2p/testing:go_default_library",
|
||||||
"//beacon-chain/rpc/core:go_default_library",
|
"//beacon-chain/rpc/core:go_default_library",
|
||||||
|
"//beacon-chain/rpc/eth/rewards:go_default_library",
|
||||||
|
"//beacon-chain/rpc/eth/rewards/testing:go_default_library",
|
||||||
"//beacon-chain/rpc/eth/shared:go_default_library",
|
"//beacon-chain/rpc/eth/shared:go_default_library",
|
||||||
"//beacon-chain/rpc/eth/shared/testing:go_default_library",
|
"//beacon-chain/rpc/eth/shared/testing:go_default_library",
|
||||||
"//beacon-chain/rpc/testutil:go_default_library",
|
"//beacon-chain/rpc/testutil:go_default_library",
|
||||||
|
|||||||
@@ -9,8 +9,11 @@ import (
|
|||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/prysmaticlabs/prysm/v4/api"
|
"github.com/prysmaticlabs/prysm/v4/api"
|
||||||
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/rewards"
|
||||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||||
|
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
|
||||||
|
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
|
||||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||||
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
|
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
|
||||||
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||||
@@ -84,16 +87,26 @@ func (s *Server) produceBlockV3(ctx context.Context, w http.ResponseWriter, r *h
|
|||||||
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
|
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
consensusBlockValue, httpError := getConsensusBlockValue(ctx, s.BlockRewardFetcher, v1alpha1resp.Block)
|
||||||
|
if httpError != nil {
|
||||||
|
http2.WriteError(w, httpError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
w.Header().Set(api.ExecutionPayloadBlindedHeader, fmt.Sprintf("%v", v1alpha1resp.IsBlinded))
|
w.Header().Set(api.ExecutionPayloadBlindedHeader, fmt.Sprintf("%v", v1alpha1resp.IsBlinded))
|
||||||
w.Header().Set(api.ExecutionPayloadValueHeader, fmt.Sprintf("%d", v1alpha1resp.PayloadValue))
|
w.Header().Set(api.ExecutionPayloadValueHeader, fmt.Sprintf("%d", v1alpha1resp.PayloadValue))
|
||||||
|
w.Header().Set(api.ConsensusBlockValueHeader, consensusBlockValue)
|
||||||
|
|
||||||
phase0Block, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Phase0)
|
phase0Block, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Phase0)
|
||||||
if ok {
|
if ok {
|
||||||
|
// rewards aren't used in phase 0
|
||||||
handleProducePhase0V3(ctx, w, isSSZ, phase0Block, v1alpha1resp.PayloadValue)
|
handleProducePhase0V3(ctx, w, isSSZ, phase0Block, v1alpha1resp.PayloadValue)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
altairBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Altair)
|
altairBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Altair)
|
||||||
if ok {
|
if ok {
|
||||||
handleProduceAltairV3(ctx, w, isSSZ, altairBlock, v1alpha1resp.PayloadValue)
|
handleProduceAltairV3(ctx, w, isSSZ, altairBlock, v1alpha1resp.PayloadValue, consensusBlockValue)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
optimistic, err := s.OptimisticModeFetcher.IsOptimistic(ctx)
|
optimistic, err := s.OptimisticModeFetcher.IsOptimistic(ctx)
|
||||||
@@ -107,36 +120,82 @@ func (s *Server) produceBlockV3(ctx context.Context, w http.ResponseWriter, r *h
|
|||||||
}
|
}
|
||||||
blindedBellatrixBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_BlindedBellatrix)
|
blindedBellatrixBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_BlindedBellatrix)
|
||||||
if ok {
|
if ok {
|
||||||
handleProduceBlindedBellatrixV3(ctx, w, isSSZ, blindedBellatrixBlock, v1alpha1resp.PayloadValue)
|
handleProduceBlindedBellatrixV3(ctx, w, isSSZ, blindedBellatrixBlock, v1alpha1resp.PayloadValue, consensusBlockValue)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
bellatrixBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Bellatrix)
|
bellatrixBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Bellatrix)
|
||||||
if ok {
|
if ok {
|
||||||
handleProduceBellatrixV3(ctx, w, isSSZ, bellatrixBlock, v1alpha1resp.PayloadValue)
|
handleProduceBellatrixV3(ctx, w, isSSZ, bellatrixBlock, v1alpha1resp.PayloadValue, consensusBlockValue)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
blindedCapellaBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_BlindedCapella)
|
blindedCapellaBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_BlindedCapella)
|
||||||
if ok {
|
if ok {
|
||||||
handleProduceBlindedCapellaV3(ctx, w, isSSZ, blindedCapellaBlock, v1alpha1resp.PayloadValue)
|
handleProduceBlindedCapellaV3(ctx, w, isSSZ, blindedCapellaBlock, v1alpha1resp.PayloadValue, consensusBlockValue)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
capellaBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Capella)
|
capellaBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Capella)
|
||||||
if ok {
|
if ok {
|
||||||
handleProduceCapellaV3(ctx, w, isSSZ, capellaBlock, v1alpha1resp.PayloadValue)
|
handleProduceCapellaV3(ctx, w, isSSZ, capellaBlock, v1alpha1resp.PayloadValue, consensusBlockValue)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
blindedDenebBlockContents, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_BlindedDeneb)
|
blindedDenebBlockContents, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_BlindedDeneb)
|
||||||
if ok {
|
if ok {
|
||||||
handleProduceBlindedDenebV3(ctx, w, isSSZ, blindedDenebBlockContents, v1alpha1resp.PayloadValue)
|
handleProduceBlindedDenebV3(ctx, w, isSSZ, blindedDenebBlockContents, v1alpha1resp.PayloadValue, consensusBlockValue)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
denebBlockContents, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Deneb)
|
denebBlockContents, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Deneb)
|
||||||
if ok {
|
if ok {
|
||||||
handleProduceDenebV3(ctx, w, isSSZ, denebBlockContents, v1alpha1resp.PayloadValue)
|
handleProduceDenebV3(ctx, w, isSSZ, denebBlockContents, v1alpha1resp.PayloadValue, consensusBlockValue)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getConsensusBlockValue(ctx context.Context, blockRewardsFetcher rewards.BlockRewardsFetcher, i interface{} /* block as argument */) (string, *http2.DefaultErrorJson) {
|
||||||
|
var wrapper interfaces.ReadOnlySignedBeaconBlock
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// TODO: we should not require this fake signed wrapper and fix associated functions in the future.
|
||||||
|
switch b := i.(type) {
|
||||||
|
case *eth.GenericBeaconBlock_Phase0:
|
||||||
|
//ignore for phase0
|
||||||
|
return "", nil
|
||||||
|
case *eth.GenericBeaconBlock_Altair:
|
||||||
|
wrapper, err = blocks.NewSignedBeaconBlock(ð.GenericSignedBeaconBlock_Altair{Altair: ð.SignedBeaconBlockAltair{Block: b.Altair}})
|
||||||
|
case *eth.GenericBeaconBlock_Bellatrix:
|
||||||
|
wrapper, err = blocks.NewSignedBeaconBlock(ð.GenericSignedBeaconBlock_Bellatrix{Bellatrix: ð.SignedBeaconBlockBellatrix{Block: b.Bellatrix}})
|
||||||
|
case *eth.GenericBeaconBlock_BlindedBellatrix:
|
||||||
|
wrapper, err = blocks.NewSignedBeaconBlock(ð.GenericSignedBeaconBlock_BlindedBellatrix{BlindedBellatrix: ð.SignedBlindedBeaconBlockBellatrix{Block: b.BlindedBellatrix}})
|
||||||
|
case *eth.GenericBeaconBlock_Capella:
|
||||||
|
wrapper, err = blocks.NewSignedBeaconBlock(ð.GenericSignedBeaconBlock_Capella{Capella: ð.SignedBeaconBlockCapella{Block: b.Capella}})
|
||||||
|
case *eth.GenericBeaconBlock_BlindedCapella:
|
||||||
|
wrapper, err = blocks.NewSignedBeaconBlock(ð.GenericSignedBeaconBlock_BlindedCapella{BlindedCapella: ð.SignedBlindedBeaconBlockCapella{Block: b.BlindedCapella}})
|
||||||
|
case *eth.GenericBeaconBlock_Deneb:
|
||||||
|
// no need for sidecar
|
||||||
|
wrapper, err = blocks.NewSignedBeaconBlock(ð.GenericSignedBeaconBlock_Deneb{Deneb: ð.SignedBeaconBlockAndBlobsDeneb{Block: ð.SignedBeaconBlockDeneb{Block: b.Deneb.Block}}})
|
||||||
|
case *eth.GenericBeaconBlock_BlindedDeneb:
|
||||||
|
// no need for sidecar
|
||||||
|
wrapper, err = blocks.NewSignedBeaconBlock(ð.GenericSignedBeaconBlock_BlindedDeneb{BlindedDeneb: ð.SignedBlindedBeaconBlockAndBlobsDeneb{SignedBlindedBlock: ð.SignedBlindedBeaconBlockDeneb{Message: b.BlindedDeneb.Block}}})
|
||||||
|
default:
|
||||||
|
return "", &http2.DefaultErrorJson{
|
||||||
|
Message: fmt.Errorf("type %T is not supported", b).Error(),
|
||||||
|
Code: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return "", &http2.DefaultErrorJson{
|
||||||
|
Message: err.Error(),
|
||||||
|
Code: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//get consensus payload value which is the same as the total from the block rewards api
|
||||||
|
blockRewards, httpError := blockRewardsFetcher.GetBlockRewardsData(ctx, wrapper)
|
||||||
|
if httpError != nil {
|
||||||
|
return "", httpError
|
||||||
|
}
|
||||||
|
return blockRewards.Total, nil
|
||||||
|
}
|
||||||
|
|
||||||
func handleProducePhase0V3(
|
func handleProducePhase0V3(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
w http.ResponseWriter,
|
w http.ResponseWriter,
|
||||||
@@ -169,6 +228,7 @@ func handleProducePhase0V3(
|
|||||||
Version: version.String(version.Phase0),
|
Version: version.String(version.Phase0),
|
||||||
ExecutionPayloadBlinded: false,
|
ExecutionPayloadBlinded: false,
|
||||||
ExecutionPayloadValue: fmt.Sprintf("%d", payloadValue), // mev not available at this point
|
ExecutionPayloadValue: fmt.Sprintf("%d", payloadValue), // mev not available at this point
|
||||||
|
ConsensusBlockValue: "", // rewards not applicable before altair
|
||||||
Data: jsonBytes,
|
Data: jsonBytes,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -178,10 +238,12 @@ func handleProduceAltairV3(
|
|||||||
w http.ResponseWriter,
|
w http.ResponseWriter,
|
||||||
isSSZ bool,
|
isSSZ bool,
|
||||||
blk *eth.GenericBeaconBlock_Altair,
|
blk *eth.GenericBeaconBlock_Altair,
|
||||||
payloadValue uint64,
|
executionPayloadValue uint64,
|
||||||
|
consensusPayloadValue string,
|
||||||
) {
|
) {
|
||||||
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceAltairV3")
|
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceAltairV3")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if isSSZ {
|
if isSSZ {
|
||||||
sszResp, err := blk.Altair.MarshalSSZ()
|
sszResp, err := blk.Altair.MarshalSSZ()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -204,7 +266,8 @@ func handleProduceAltairV3(
|
|||||||
http2.WriteJson(w, &ProduceBlockV3Response{
|
http2.WriteJson(w, &ProduceBlockV3Response{
|
||||||
Version: version.String(version.Altair),
|
Version: version.String(version.Altair),
|
||||||
ExecutionPayloadBlinded: false,
|
ExecutionPayloadBlinded: false,
|
||||||
ExecutionPayloadValue: fmt.Sprintf("%d", payloadValue), // mev not available at this point
|
ExecutionPayloadValue: fmt.Sprintf("%d", executionPayloadValue), // mev not available at this point
|
||||||
|
ConsensusBlockValue: consensusPayloadValue,
|
||||||
Data: jsonBytes,
|
Data: jsonBytes,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -214,7 +277,8 @@ func handleProduceBellatrixV3(
|
|||||||
w http.ResponseWriter,
|
w http.ResponseWriter,
|
||||||
isSSZ bool,
|
isSSZ bool,
|
||||||
blk *eth.GenericBeaconBlock_Bellatrix,
|
blk *eth.GenericBeaconBlock_Bellatrix,
|
||||||
payloadValue uint64,
|
executionPayloadValue uint64,
|
||||||
|
consensusPayloadValue string,
|
||||||
) {
|
) {
|
||||||
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceBellatrixV3")
|
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceBellatrixV3")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -240,7 +304,8 @@ func handleProduceBellatrixV3(
|
|||||||
http2.WriteJson(w, &ProduceBlockV3Response{
|
http2.WriteJson(w, &ProduceBlockV3Response{
|
||||||
Version: version.String(version.Bellatrix),
|
Version: version.String(version.Bellatrix),
|
||||||
ExecutionPayloadBlinded: false,
|
ExecutionPayloadBlinded: false,
|
||||||
ExecutionPayloadValue: fmt.Sprintf("%d", payloadValue), // mev not available at this point
|
ExecutionPayloadValue: fmt.Sprintf("%d", executionPayloadValue), // mev not available at this point
|
||||||
|
ConsensusBlockValue: consensusPayloadValue,
|
||||||
Data: jsonBytes,
|
Data: jsonBytes,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -250,7 +315,8 @@ func handleProduceBlindedBellatrixV3(
|
|||||||
w http.ResponseWriter,
|
w http.ResponseWriter,
|
||||||
isSSZ bool,
|
isSSZ bool,
|
||||||
blk *eth.GenericBeaconBlock_BlindedBellatrix,
|
blk *eth.GenericBeaconBlock_BlindedBellatrix,
|
||||||
payloadValue uint64,
|
executionPayloadValue uint64,
|
||||||
|
consensusPayloadValue string,
|
||||||
) {
|
) {
|
||||||
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceBlindedBellatrixV3")
|
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceBlindedBellatrixV3")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -276,7 +342,8 @@ func handleProduceBlindedBellatrixV3(
|
|||||||
http2.WriteJson(w, &ProduceBlockV3Response{
|
http2.WriteJson(w, &ProduceBlockV3Response{
|
||||||
Version: version.String(version.Bellatrix),
|
Version: version.String(version.Bellatrix),
|
||||||
ExecutionPayloadBlinded: true,
|
ExecutionPayloadBlinded: true,
|
||||||
ExecutionPayloadValue: fmt.Sprintf("%d", payloadValue),
|
ExecutionPayloadValue: fmt.Sprintf("%d", executionPayloadValue),
|
||||||
|
ConsensusBlockValue: consensusPayloadValue,
|
||||||
Data: jsonBytes,
|
Data: jsonBytes,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -286,7 +353,8 @@ func handleProduceBlindedCapellaV3(
|
|||||||
w http.ResponseWriter,
|
w http.ResponseWriter,
|
||||||
isSSZ bool,
|
isSSZ bool,
|
||||||
blk *eth.GenericBeaconBlock_BlindedCapella,
|
blk *eth.GenericBeaconBlock_BlindedCapella,
|
||||||
payloadValue uint64,
|
executionPayloadValue uint64,
|
||||||
|
consensusPayloadValue string,
|
||||||
) {
|
) {
|
||||||
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceBlindedCapellaV3")
|
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceBlindedCapellaV3")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -312,7 +380,8 @@ func handleProduceBlindedCapellaV3(
|
|||||||
http2.WriteJson(w, &ProduceBlockV3Response{
|
http2.WriteJson(w, &ProduceBlockV3Response{
|
||||||
Version: version.String(version.Capella),
|
Version: version.String(version.Capella),
|
||||||
ExecutionPayloadBlinded: true,
|
ExecutionPayloadBlinded: true,
|
||||||
ExecutionPayloadValue: fmt.Sprintf("%d", payloadValue),
|
ExecutionPayloadValue: fmt.Sprintf("%d", executionPayloadValue),
|
||||||
|
ConsensusBlockValue: consensusPayloadValue,
|
||||||
Data: jsonBytes,
|
Data: jsonBytes,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -322,7 +391,8 @@ func handleProduceCapellaV3(
|
|||||||
w http.ResponseWriter,
|
w http.ResponseWriter,
|
||||||
isSSZ bool,
|
isSSZ bool,
|
||||||
blk *eth.GenericBeaconBlock_Capella,
|
blk *eth.GenericBeaconBlock_Capella,
|
||||||
payloadValue uint64,
|
executionPayloadValue uint64,
|
||||||
|
consensusPayloadValue string,
|
||||||
) {
|
) {
|
||||||
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceCapellaV3")
|
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceCapellaV3")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -348,7 +418,8 @@ func handleProduceCapellaV3(
|
|||||||
http2.WriteJson(w, &ProduceBlockV3Response{
|
http2.WriteJson(w, &ProduceBlockV3Response{
|
||||||
Version: version.String(version.Capella),
|
Version: version.String(version.Capella),
|
||||||
ExecutionPayloadBlinded: false,
|
ExecutionPayloadBlinded: false,
|
||||||
ExecutionPayloadValue: fmt.Sprintf("%d", payloadValue), // mev not available at this point
|
ExecutionPayloadValue: fmt.Sprintf("%d", executionPayloadValue), // mev not available at this point
|
||||||
|
ConsensusBlockValue: consensusPayloadValue,
|
||||||
Data: jsonBytes,
|
Data: jsonBytes,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -358,7 +429,8 @@ func handleProduceBlindedDenebV3(
|
|||||||
w http.ResponseWriter,
|
w http.ResponseWriter,
|
||||||
isSSZ bool,
|
isSSZ bool,
|
||||||
blk *eth.GenericBeaconBlock_BlindedDeneb,
|
blk *eth.GenericBeaconBlock_BlindedDeneb,
|
||||||
payloadValue uint64,
|
executionPayloadValue uint64,
|
||||||
|
consensusPayloadValue string,
|
||||||
) {
|
) {
|
||||||
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceBlindedDenebV3")
|
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceBlindedDenebV3")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -384,7 +456,8 @@ func handleProduceBlindedDenebV3(
|
|||||||
http2.WriteJson(w, &ProduceBlockV3Response{
|
http2.WriteJson(w, &ProduceBlockV3Response{
|
||||||
Version: version.String(version.Deneb),
|
Version: version.String(version.Deneb),
|
||||||
ExecutionPayloadBlinded: true,
|
ExecutionPayloadBlinded: true,
|
||||||
ExecutionPayloadValue: fmt.Sprintf("%d", payloadValue),
|
ExecutionPayloadValue: fmt.Sprintf("%d", executionPayloadValue),
|
||||||
|
ConsensusBlockValue: consensusPayloadValue,
|
||||||
Data: jsonBytes,
|
Data: jsonBytes,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -394,7 +467,8 @@ func handleProduceDenebV3(
|
|||||||
w http.ResponseWriter,
|
w http.ResponseWriter,
|
||||||
isSSZ bool,
|
isSSZ bool,
|
||||||
blk *eth.GenericBeaconBlock_Deneb,
|
blk *eth.GenericBeaconBlock_Deneb,
|
||||||
payloadValue uint64,
|
executionPayloadValue uint64,
|
||||||
|
consensusBlockValue string,
|
||||||
) {
|
) {
|
||||||
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceDenebV3")
|
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceDenebV3")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -420,7 +494,8 @@ func handleProduceDenebV3(
|
|||||||
http2.WriteJson(w, &ProduceBlockV3Response{
|
http2.WriteJson(w, &ProduceBlockV3Response{
|
||||||
Version: version.String(version.Deneb),
|
Version: version.String(version.Deneb),
|
||||||
ExecutionPayloadBlinded: false,
|
ExecutionPayloadBlinded: false,
|
||||||
ExecutionPayloadValue: fmt.Sprintf("%d", payloadValue), // mev not available at this point
|
ExecutionPayloadValue: fmt.Sprintf("%d", executionPayloadValue), // mev not available at this point
|
||||||
|
ConsensusBlockValue: consensusBlockValue,
|
||||||
Data: jsonBytes,
|
Data: jsonBytes,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import (
|
|||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/prysmaticlabs/prysm/v4/api"
|
"github.com/prysmaticlabs/prysm/v4/api"
|
||||||
blockchainTesting "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
|
blockchainTesting "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
|
||||||
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/rewards"
|
||||||
|
rewardtesting "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/rewards/testing"
|
||||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
||||||
rpctesting "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared/testing"
|
rpctesting "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared/testing"
|
||||||
mockSync "github.com/prysmaticlabs/prysm/v4/beacon-chain/sync/initial-sync/testing"
|
mockSync "github.com/prysmaticlabs/prysm/v4/beacon-chain/sync/initial-sync/testing"
|
||||||
@@ -46,26 +48,31 @@ func TestProduceBlockV3(t *testing.T) {
|
|||||||
writer.Body = &bytes.Buffer{}
|
writer.Body = &bytes.Buffer{}
|
||||||
server.ProduceBlockV3(writer, request)
|
server.ProduceBlockV3(writer, request)
|
||||||
assert.Equal(t, http.StatusOK, writer.Code)
|
assert.Equal(t, http.StatusOK, writer.Code)
|
||||||
want := fmt.Sprintf(`{"version":"phase0","execution_payload_blinded":false,"execution_payload_value":"0","data":%s}`, string(jsonBytes))
|
want := fmt.Sprintf(`{"version":"phase0","execution_payload_blinded":false,"execution_payload_value":"0","consensus_block_value":"","data":%s}`, string(jsonBytes))
|
||||||
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
|
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
|
||||||
require.Equal(t, want, body)
|
require.Equal(t, want, body)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
||||||
|
require.Equal(t, writer.Header().Get(api.ConsensusBlockValueHeader) == "", true)
|
||||||
})
|
})
|
||||||
t.Run("Altair", func(t *testing.T) {
|
t.Run("Altair", func(t *testing.T) {
|
||||||
var block *shared.SignedBeaconBlockAltair
|
var block *shared.SignedBeaconBlockAltair
|
||||||
err := json.Unmarshal([]byte(rpctesting.AltairBlock), &block)
|
err := json.Unmarshal([]byte(rpctesting.AltairBlock), &block)
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
jsonBytes, err := json.Marshal(block.Message)
|
jsonBytes, err := json.Marshal(block.Message)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
|
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
|
||||||
v1alpha1Server.EXPECT().GetBeaconBlock(gomock.Any(), gomock.Any()).Return(
|
v1alpha1Server.EXPECT().GetBeaconBlock(gomock.Any(), gomock.Any()).Return(
|
||||||
func() (*eth.GenericBeaconBlock, error) {
|
func() (*eth.GenericBeaconBlock, error) {
|
||||||
|
|
||||||
return block.Message.ToGeneric()
|
return block.Message.ToGeneric()
|
||||||
}())
|
}())
|
||||||
|
mockRewards := &rewards.BlockRewards{Total: "10"}
|
||||||
server := &Server{
|
server := &Server{
|
||||||
V1Alpha1Server: v1alpha1Server,
|
V1Alpha1Server: v1alpha1Server,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
|
BlockRewardFetcher: &rewardtesting.MockBlockRewardFetcher{Rewards: mockRewards},
|
||||||
}
|
}
|
||||||
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
||||||
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
||||||
@@ -74,11 +81,12 @@ func TestProduceBlockV3(t *testing.T) {
|
|||||||
writer.Body = &bytes.Buffer{}
|
writer.Body = &bytes.Buffer{}
|
||||||
server.ProduceBlockV3(writer, request)
|
server.ProduceBlockV3(writer, request)
|
||||||
assert.Equal(t, http.StatusOK, writer.Code)
|
assert.Equal(t, http.StatusOK, writer.Code)
|
||||||
want := fmt.Sprintf(`{"version":"altair","execution_payload_blinded":false,"execution_payload_value":"0","data":%s}`, string(jsonBytes))
|
want := fmt.Sprintf(`{"version":"altair","execution_payload_blinded":false,"execution_payload_value":"0","consensus_block_value":"10","data":%s}`, string(jsonBytes))
|
||||||
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
|
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
|
||||||
require.Equal(t, want, body)
|
require.Equal(t, want, body)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
||||||
|
require.Equal(t, writer.Header().Get(api.ConsensusBlockValueHeader) == "10", true)
|
||||||
})
|
})
|
||||||
t.Run("Bellatrix", func(t *testing.T) {
|
t.Run("Bellatrix", func(t *testing.T) {
|
||||||
var block *shared.SignedBeaconBlockBellatrix
|
var block *shared.SignedBeaconBlockBellatrix
|
||||||
@@ -92,10 +100,12 @@ func TestProduceBlockV3(t *testing.T) {
|
|||||||
return block.Message.ToGeneric()
|
return block.Message.ToGeneric()
|
||||||
}())
|
}())
|
||||||
mockChainService := &blockchainTesting.ChainService{}
|
mockChainService := &blockchainTesting.ChainService{}
|
||||||
|
mockRewards := &rewards.BlockRewards{Total: "10"}
|
||||||
server := &Server{
|
server := &Server{
|
||||||
V1Alpha1Server: v1alpha1Server,
|
V1Alpha1Server: v1alpha1Server,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
OptimisticModeFetcher: mockChainService,
|
OptimisticModeFetcher: mockChainService,
|
||||||
|
BlockRewardFetcher: &rewardtesting.MockBlockRewardFetcher{Rewards: mockRewards},
|
||||||
}
|
}
|
||||||
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
||||||
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
||||||
@@ -104,11 +114,12 @@ func TestProduceBlockV3(t *testing.T) {
|
|||||||
writer.Body = &bytes.Buffer{}
|
writer.Body = &bytes.Buffer{}
|
||||||
server.ProduceBlockV3(writer, request)
|
server.ProduceBlockV3(writer, request)
|
||||||
assert.Equal(t, http.StatusOK, writer.Code)
|
assert.Equal(t, http.StatusOK, writer.Code)
|
||||||
want := fmt.Sprintf(`{"version":"bellatrix","execution_payload_blinded":false,"execution_payload_value":"0","data":%s}`, string(jsonBytes))
|
want := fmt.Sprintf(`{"version":"bellatrix","execution_payload_blinded":false,"execution_payload_value":"0","consensus_block_value":"10","data":%s}`, string(jsonBytes))
|
||||||
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
|
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
|
||||||
require.Equal(t, want, body)
|
require.Equal(t, want, body)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
||||||
|
require.Equal(t, writer.Header().Get(api.ConsensusBlockValueHeader) == "10", true)
|
||||||
})
|
})
|
||||||
t.Run("BlindedBellatrix", func(t *testing.T) {
|
t.Run("BlindedBellatrix", func(t *testing.T) {
|
||||||
var block *shared.SignedBlindedBeaconBlockBellatrix
|
var block *shared.SignedBlindedBeaconBlockBellatrix
|
||||||
@@ -122,10 +133,12 @@ func TestProduceBlockV3(t *testing.T) {
|
|||||||
return block.Message.ToGeneric()
|
return block.Message.ToGeneric()
|
||||||
}())
|
}())
|
||||||
mockChainService := &blockchainTesting.ChainService{}
|
mockChainService := &blockchainTesting.ChainService{}
|
||||||
|
mockRewards := &rewards.BlockRewards{Total: "10"}
|
||||||
server := &Server{
|
server := &Server{
|
||||||
V1Alpha1Server: v1alpha1Server,
|
V1Alpha1Server: v1alpha1Server,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
OptimisticModeFetcher: mockChainService,
|
OptimisticModeFetcher: mockChainService,
|
||||||
|
BlockRewardFetcher: &rewardtesting.MockBlockRewardFetcher{Rewards: mockRewards},
|
||||||
}
|
}
|
||||||
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
||||||
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
||||||
@@ -134,11 +147,12 @@ func TestProduceBlockV3(t *testing.T) {
|
|||||||
writer.Body = &bytes.Buffer{}
|
writer.Body = &bytes.Buffer{}
|
||||||
server.ProduceBlockV3(writer, request)
|
server.ProduceBlockV3(writer, request)
|
||||||
assert.Equal(t, http.StatusOK, writer.Code)
|
assert.Equal(t, http.StatusOK, writer.Code)
|
||||||
want := fmt.Sprintf(`{"version":"bellatrix","execution_payload_blinded":true,"execution_payload_value":"0","data":%s}`, string(jsonBytes))
|
want := fmt.Sprintf(`{"version":"bellatrix","execution_payload_blinded":true,"execution_payload_value":"0","consensus_block_value":"10","data":%s}`, string(jsonBytes))
|
||||||
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
|
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
|
||||||
require.Equal(t, want, body)
|
require.Equal(t, want, body)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "true", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "true", true)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
||||||
|
require.Equal(t, writer.Header().Get(api.ConsensusBlockValueHeader) == "10", true)
|
||||||
})
|
})
|
||||||
t.Run("Capella", func(t *testing.T) {
|
t.Run("Capella", func(t *testing.T) {
|
||||||
var block *shared.SignedBeaconBlockCapella
|
var block *shared.SignedBeaconBlockCapella
|
||||||
@@ -152,10 +166,12 @@ func TestProduceBlockV3(t *testing.T) {
|
|||||||
return block.Message.ToGeneric()
|
return block.Message.ToGeneric()
|
||||||
}())
|
}())
|
||||||
mockChainService := &blockchainTesting.ChainService{}
|
mockChainService := &blockchainTesting.ChainService{}
|
||||||
|
mockRewards := &rewards.BlockRewards{Total: "10"}
|
||||||
server := &Server{
|
server := &Server{
|
||||||
V1Alpha1Server: v1alpha1Server,
|
V1Alpha1Server: v1alpha1Server,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
OptimisticModeFetcher: mockChainService,
|
OptimisticModeFetcher: mockChainService,
|
||||||
|
BlockRewardFetcher: &rewardtesting.MockBlockRewardFetcher{Rewards: mockRewards},
|
||||||
}
|
}
|
||||||
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
||||||
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
||||||
@@ -164,11 +180,12 @@ func TestProduceBlockV3(t *testing.T) {
|
|||||||
writer.Body = &bytes.Buffer{}
|
writer.Body = &bytes.Buffer{}
|
||||||
server.ProduceBlockV3(writer, request)
|
server.ProduceBlockV3(writer, request)
|
||||||
assert.Equal(t, http.StatusOK, writer.Code)
|
assert.Equal(t, http.StatusOK, writer.Code)
|
||||||
want := fmt.Sprintf(`{"version":"capella","execution_payload_blinded":false,"execution_payload_value":"0","data":%s}`, string(jsonBytes))
|
want := fmt.Sprintf(`{"version":"capella","execution_payload_blinded":false,"execution_payload_value":"0","consensus_block_value":"10","data":%s}`, string(jsonBytes))
|
||||||
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
|
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
|
||||||
require.Equal(t, want, body)
|
require.Equal(t, want, body)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
||||||
|
require.Equal(t, writer.Header().Get(api.ConsensusBlockValueHeader) == "10", true)
|
||||||
})
|
})
|
||||||
t.Run("Blinded Capella", func(t *testing.T) {
|
t.Run("Blinded Capella", func(t *testing.T) {
|
||||||
var block *shared.SignedBlindedBeaconBlockCapella
|
var block *shared.SignedBlindedBeaconBlockCapella
|
||||||
@@ -185,10 +202,12 @@ func TestProduceBlockV3(t *testing.T) {
|
|||||||
return g, err
|
return g, err
|
||||||
}())
|
}())
|
||||||
mockChainService := &blockchainTesting.ChainService{}
|
mockChainService := &blockchainTesting.ChainService{}
|
||||||
|
mockRewards := &rewards.BlockRewards{Total: "10"}
|
||||||
server := &Server{
|
server := &Server{
|
||||||
V1Alpha1Server: v1alpha1Server,
|
V1Alpha1Server: v1alpha1Server,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
OptimisticModeFetcher: mockChainService,
|
OptimisticModeFetcher: mockChainService,
|
||||||
|
BlockRewardFetcher: &rewardtesting.MockBlockRewardFetcher{Rewards: mockRewards},
|
||||||
}
|
}
|
||||||
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
||||||
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
||||||
@@ -197,11 +216,12 @@ func TestProduceBlockV3(t *testing.T) {
|
|||||||
writer.Body = &bytes.Buffer{}
|
writer.Body = &bytes.Buffer{}
|
||||||
server.ProduceBlockV3(writer, request)
|
server.ProduceBlockV3(writer, request)
|
||||||
assert.Equal(t, http.StatusOK, writer.Code)
|
assert.Equal(t, http.StatusOK, writer.Code)
|
||||||
want := fmt.Sprintf(`{"version":"capella","execution_payload_blinded":true,"execution_payload_value":"2000","data":%s}`, string(jsonBytes))
|
want := fmt.Sprintf(`{"version":"capella","execution_payload_blinded":true,"execution_payload_value":"2000","consensus_block_value":"10","data":%s}`, string(jsonBytes))
|
||||||
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
|
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
|
||||||
require.Equal(t, want, body)
|
require.Equal(t, want, body)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "true", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "true", true)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "2000", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "2000", true)
|
||||||
|
require.Equal(t, writer.Header().Get(api.ConsensusBlockValueHeader) == "10", true)
|
||||||
})
|
})
|
||||||
t.Run("Deneb", func(t *testing.T) {
|
t.Run("Deneb", func(t *testing.T) {
|
||||||
var block *shared.SignedBeaconBlockContentsDeneb
|
var block *shared.SignedBeaconBlockContentsDeneb
|
||||||
@@ -215,10 +235,12 @@ func TestProduceBlockV3(t *testing.T) {
|
|||||||
return block.ToUnsigned().ToGeneric()
|
return block.ToUnsigned().ToGeneric()
|
||||||
}())
|
}())
|
||||||
mockChainService := &blockchainTesting.ChainService{}
|
mockChainService := &blockchainTesting.ChainService{}
|
||||||
|
mockRewards := &rewards.BlockRewards{Total: "10"}
|
||||||
server := &Server{
|
server := &Server{
|
||||||
V1Alpha1Server: v1alpha1Server,
|
V1Alpha1Server: v1alpha1Server,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
OptimisticModeFetcher: mockChainService,
|
OptimisticModeFetcher: mockChainService,
|
||||||
|
BlockRewardFetcher: &rewardtesting.MockBlockRewardFetcher{Rewards: mockRewards},
|
||||||
}
|
}
|
||||||
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
||||||
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
||||||
@@ -227,11 +249,12 @@ func TestProduceBlockV3(t *testing.T) {
|
|||||||
writer.Body = &bytes.Buffer{}
|
writer.Body = &bytes.Buffer{}
|
||||||
server.ProduceBlockV3(writer, request)
|
server.ProduceBlockV3(writer, request)
|
||||||
assert.Equal(t, http.StatusOK, writer.Code)
|
assert.Equal(t, http.StatusOK, writer.Code)
|
||||||
want := fmt.Sprintf(`{"version":"deneb","execution_payload_blinded":false,"execution_payload_value":"0","data":%s}`, string(jsonBytes))
|
want := fmt.Sprintf(`{"version":"deneb","execution_payload_blinded":false,"execution_payload_value":"0","consensus_block_value":"10","data":%s}`, string(jsonBytes))
|
||||||
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
|
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
|
||||||
require.Equal(t, want, body)
|
require.Equal(t, want, body)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
||||||
|
require.Equal(t, writer.Header().Get(api.ConsensusBlockValueHeader) == "10", true)
|
||||||
})
|
})
|
||||||
t.Run("Blinded Deneb", func(t *testing.T) {
|
t.Run("Blinded Deneb", func(t *testing.T) {
|
||||||
var block *shared.SignedBlindedBeaconBlockContentsDeneb
|
var block *shared.SignedBlindedBeaconBlockContentsDeneb
|
||||||
@@ -245,10 +268,12 @@ func TestProduceBlockV3(t *testing.T) {
|
|||||||
return block.ToUnsigned().ToGeneric()
|
return block.ToUnsigned().ToGeneric()
|
||||||
}())
|
}())
|
||||||
mockChainService := &blockchainTesting.ChainService{}
|
mockChainService := &blockchainTesting.ChainService{}
|
||||||
|
mockRewards := &rewards.BlockRewards{Total: "10"}
|
||||||
server := &Server{
|
server := &Server{
|
||||||
V1Alpha1Server: v1alpha1Server,
|
V1Alpha1Server: v1alpha1Server,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
OptimisticModeFetcher: mockChainService,
|
OptimisticModeFetcher: mockChainService,
|
||||||
|
BlockRewardFetcher: &rewardtesting.MockBlockRewardFetcher{Rewards: mockRewards},
|
||||||
}
|
}
|
||||||
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
||||||
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
||||||
@@ -257,11 +282,12 @@ func TestProduceBlockV3(t *testing.T) {
|
|||||||
writer.Body = &bytes.Buffer{}
|
writer.Body = &bytes.Buffer{}
|
||||||
server.ProduceBlockV3(writer, request)
|
server.ProduceBlockV3(writer, request)
|
||||||
assert.Equal(t, http.StatusOK, writer.Code)
|
assert.Equal(t, http.StatusOK, writer.Code)
|
||||||
want := fmt.Sprintf(`{"version":"deneb","execution_payload_blinded":true,"execution_payload_value":"0","data":%s}`, string(jsonBytes))
|
want := fmt.Sprintf(`{"version":"deneb","execution_payload_blinded":true,"execution_payload_value":"0","consensus_block_value":"10","data":%s}`, string(jsonBytes))
|
||||||
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
|
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
|
||||||
require.Equal(t, want, body)
|
require.Equal(t, want, body)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "true", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "true", true)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
||||||
|
require.Equal(t, writer.Header().Get(api.ConsensusBlockValueHeader) == "10", true)
|
||||||
})
|
})
|
||||||
t.Run("invalid query parameter slot empty", func(t *testing.T) {
|
t.Run("invalid query parameter slot empty", func(t *testing.T) {
|
||||||
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
|
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
|
||||||
@@ -321,6 +347,7 @@ func TestProduceBlockV3(t *testing.T) {
|
|||||||
|
|
||||||
func TestProduceBlockV3SSZ(t *testing.T) {
|
func TestProduceBlockV3SSZ(t *testing.T) {
|
||||||
ctrl := gomock.NewController(t)
|
ctrl := gomock.NewController(t)
|
||||||
|
mockRewards := &rewards.BlockRewards{Total: "10"}
|
||||||
t.Run("Phase 0", func(t *testing.T) {
|
t.Run("Phase 0", func(t *testing.T) {
|
||||||
var block *shared.SignedBeaconBlock
|
var block *shared.SignedBeaconBlock
|
||||||
err := json.Unmarshal([]byte(rpctesting.Phase0Block), &block)
|
err := json.Unmarshal([]byte(rpctesting.Phase0Block), &block)
|
||||||
@@ -351,6 +378,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
|
|||||||
require.Equal(t, string(ssz), writer.Body.String())
|
require.Equal(t, string(ssz), writer.Body.String())
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
||||||
|
require.Equal(t, writer.Header().Get(api.ConsensusBlockValueHeader) == "", true)
|
||||||
})
|
})
|
||||||
t.Run("Altair", func(t *testing.T) {
|
t.Run("Altair", func(t *testing.T) {
|
||||||
var block *shared.SignedBeaconBlockAltair
|
var block *shared.SignedBeaconBlockAltair
|
||||||
@@ -361,9 +389,11 @@ func TestProduceBlockV3SSZ(t *testing.T) {
|
|||||||
func() (*eth.GenericBeaconBlock, error) {
|
func() (*eth.GenericBeaconBlock, error) {
|
||||||
return block.Message.ToGeneric()
|
return block.Message.ToGeneric()
|
||||||
}())
|
}())
|
||||||
|
|
||||||
server := &Server{
|
server := &Server{
|
||||||
V1Alpha1Server: v1alpha1Server,
|
V1Alpha1Server: v1alpha1Server,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
|
BlockRewardFetcher: &rewardtesting.MockBlockRewardFetcher{Rewards: mockRewards},
|
||||||
}
|
}
|
||||||
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
||||||
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
||||||
@@ -382,6 +412,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
|
|||||||
require.Equal(t, string(ssz), writer.Body.String())
|
require.Equal(t, string(ssz), writer.Body.String())
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
||||||
|
require.Equal(t, writer.Header().Get(api.ConsensusBlockValueHeader) == "10", true)
|
||||||
})
|
})
|
||||||
t.Run("Bellatrix", func(t *testing.T) {
|
t.Run("Bellatrix", func(t *testing.T) {
|
||||||
var block *shared.SignedBeaconBlockBellatrix
|
var block *shared.SignedBeaconBlockBellatrix
|
||||||
@@ -397,6 +428,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
|
|||||||
V1Alpha1Server: v1alpha1Server,
|
V1Alpha1Server: v1alpha1Server,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
OptimisticModeFetcher: mockChainService,
|
OptimisticModeFetcher: mockChainService,
|
||||||
|
BlockRewardFetcher: &rewardtesting.MockBlockRewardFetcher{Rewards: mockRewards},
|
||||||
}
|
}
|
||||||
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
||||||
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
||||||
@@ -415,6 +447,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
|
|||||||
require.Equal(t, string(ssz), writer.Body.String())
|
require.Equal(t, string(ssz), writer.Body.String())
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
||||||
|
require.Equal(t, writer.Header().Get(api.ConsensusBlockValueHeader) == "10", true)
|
||||||
})
|
})
|
||||||
t.Run("BlindedBellatrix", func(t *testing.T) {
|
t.Run("BlindedBellatrix", func(t *testing.T) {
|
||||||
var block *shared.SignedBlindedBeaconBlockBellatrix
|
var block *shared.SignedBlindedBeaconBlockBellatrix
|
||||||
@@ -430,6 +463,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
|
|||||||
V1Alpha1Server: v1alpha1Server,
|
V1Alpha1Server: v1alpha1Server,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
OptimisticModeFetcher: mockChainService,
|
OptimisticModeFetcher: mockChainService,
|
||||||
|
BlockRewardFetcher: &rewardtesting.MockBlockRewardFetcher{Rewards: mockRewards},
|
||||||
}
|
}
|
||||||
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
||||||
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
||||||
@@ -448,6 +482,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
|
|||||||
require.Equal(t, string(ssz), writer.Body.String())
|
require.Equal(t, string(ssz), writer.Body.String())
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "true", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "true", true)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
||||||
|
require.Equal(t, writer.Header().Get(api.ConsensusBlockValueHeader) == "10", true)
|
||||||
})
|
})
|
||||||
t.Run("Capella", func(t *testing.T) {
|
t.Run("Capella", func(t *testing.T) {
|
||||||
var block *shared.SignedBeaconBlockCapella
|
var block *shared.SignedBeaconBlockCapella
|
||||||
@@ -463,6 +498,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
|
|||||||
V1Alpha1Server: v1alpha1Server,
|
V1Alpha1Server: v1alpha1Server,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
OptimisticModeFetcher: mockChainService,
|
OptimisticModeFetcher: mockChainService,
|
||||||
|
BlockRewardFetcher: &rewardtesting.MockBlockRewardFetcher{Rewards: mockRewards},
|
||||||
}
|
}
|
||||||
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
||||||
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
||||||
@@ -481,6 +517,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
|
|||||||
require.Equal(t, string(ssz), writer.Body.String())
|
require.Equal(t, string(ssz), writer.Body.String())
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
||||||
|
require.Equal(t, writer.Header().Get(api.ConsensusBlockValueHeader) == "10", true)
|
||||||
})
|
})
|
||||||
t.Run("Blinded Capella", func(t *testing.T) {
|
t.Run("Blinded Capella", func(t *testing.T) {
|
||||||
var block *shared.SignedBlindedBeaconBlockCapella
|
var block *shared.SignedBlindedBeaconBlockCapella
|
||||||
@@ -499,6 +536,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
|
|||||||
V1Alpha1Server: v1alpha1Server,
|
V1Alpha1Server: v1alpha1Server,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
OptimisticModeFetcher: mockChainService,
|
OptimisticModeFetcher: mockChainService,
|
||||||
|
BlockRewardFetcher: &rewardtesting.MockBlockRewardFetcher{Rewards: mockRewards},
|
||||||
}
|
}
|
||||||
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
||||||
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
||||||
@@ -517,6 +555,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
|
|||||||
require.Equal(t, string(ssz), writer.Body.String())
|
require.Equal(t, string(ssz), writer.Body.String())
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "true", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "true", true)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "2000", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "2000", true)
|
||||||
|
require.Equal(t, writer.Header().Get(api.ConsensusBlockValueHeader) == "10", true)
|
||||||
})
|
})
|
||||||
t.Run("Deneb", func(t *testing.T) {
|
t.Run("Deneb", func(t *testing.T) {
|
||||||
var block *shared.SignedBeaconBlockContentsDeneb
|
var block *shared.SignedBeaconBlockContentsDeneb
|
||||||
@@ -532,6 +571,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
|
|||||||
V1Alpha1Server: v1alpha1Server,
|
V1Alpha1Server: v1alpha1Server,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
OptimisticModeFetcher: mockChainService,
|
OptimisticModeFetcher: mockChainService,
|
||||||
|
BlockRewardFetcher: &rewardtesting.MockBlockRewardFetcher{Rewards: mockRewards},
|
||||||
}
|
}
|
||||||
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
||||||
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
||||||
@@ -550,6 +590,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
|
|||||||
require.Equal(t, string(ssz), writer.Body.String())
|
require.Equal(t, string(ssz), writer.Body.String())
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
||||||
|
require.Equal(t, writer.Header().Get(api.ConsensusBlockValueHeader) == "10", true)
|
||||||
})
|
})
|
||||||
t.Run("Blinded Deneb", func(t *testing.T) {
|
t.Run("Blinded Deneb", func(t *testing.T) {
|
||||||
var block *shared.SignedBlindedBeaconBlockContentsDeneb
|
var block *shared.SignedBlindedBeaconBlockContentsDeneb
|
||||||
@@ -565,6 +606,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
|
|||||||
V1Alpha1Server: v1alpha1Server,
|
V1Alpha1Server: v1alpha1Server,
|
||||||
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
SyncChecker: &mockSync.Sync{IsSyncing: false},
|
||||||
OptimisticModeFetcher: mockChainService,
|
OptimisticModeFetcher: mockChainService,
|
||||||
|
BlockRewardFetcher: &rewardtesting.MockBlockRewardFetcher{Rewards: mockRewards},
|
||||||
}
|
}
|
||||||
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
|
||||||
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
|
||||||
@@ -583,5 +625,6 @@ func TestProduceBlockV3SSZ(t *testing.T) {
|
|||||||
require.Equal(t, string(ssz), writer.Body.String())
|
require.Equal(t, string(ssz), writer.Body.String())
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "true", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "true", true)
|
||||||
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
|
||||||
|
require.Equal(t, writer.Header().Get(api.ConsensusBlockValueHeader) == "10", true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/operations/synccommittee"
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/operations/synccommittee"
|
||||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p"
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p"
|
||||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/core"
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/core"
|
||||||
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/rewards"
|
||||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
|
||||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/sync"
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/sync"
|
||||||
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||||
@@ -34,4 +35,5 @@ type Server struct {
|
|||||||
BlockBuilder builder.BlockBuilder
|
BlockBuilder builder.BlockBuilder
|
||||||
OperationNotifier operation.Notifier
|
OperationNotifier operation.Notifier
|
||||||
CoreService *core.Service
|
CoreService *core.Service
|
||||||
|
BlockRewardFetcher rewards.BlockRewardsFetcher
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ type ProduceBlockV3Response struct {
|
|||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
ExecutionPayloadBlinded bool `json:"execution_payload_blinded"`
|
ExecutionPayloadBlinded bool `json:"execution_payload_blinded"`
|
||||||
ExecutionPayloadValue string `json:"execution_payload_value"`
|
ExecutionPayloadValue string `json:"execution_payload_value"`
|
||||||
|
ConsensusBlockValue string `json:"consensus_block_value"`
|
||||||
Data json.RawMessage `json:"data"` // represents the block values based on the version
|
Data json.RawMessage `json:"data"` // represents the block values based on the version
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -211,15 +211,15 @@ func (s *Service) Start() {
|
|||||||
BeaconDB: s.cfg.BeaconDB,
|
BeaconDB: s.cfg.BeaconDB,
|
||||||
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
|
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
|
||||||
}
|
}
|
||||||
|
rewardFetcher := &rewards.BlockRewardService{Replayer: ch}
|
||||||
rewardsServer := &rewards.Server{
|
rewardsServer := &rewards.Server{
|
||||||
Blocker: blocker,
|
Blocker: blocker,
|
||||||
OptimisticModeFetcher: s.cfg.OptimisticModeFetcher,
|
OptimisticModeFetcher: s.cfg.OptimisticModeFetcher,
|
||||||
FinalizationFetcher: s.cfg.FinalizationFetcher,
|
FinalizationFetcher: s.cfg.FinalizationFetcher,
|
||||||
ReplayerBuilder: ch,
|
|
||||||
TimeFetcher: s.cfg.GenesisTimeFetcher,
|
TimeFetcher: s.cfg.GenesisTimeFetcher,
|
||||||
Stater: stater,
|
Stater: stater,
|
||||||
HeadFetcher: s.cfg.HeadFetcher,
|
HeadFetcher: s.cfg.HeadFetcher,
|
||||||
|
BlockRewardFetcher: rewardFetcher,
|
||||||
}
|
}
|
||||||
|
|
||||||
s.cfg.Router.HandleFunc("/eth/v1/beacon/rewards/blocks/{block_id}", rewardsServer.BlockRewards).Methods(http.MethodGet)
|
s.cfg.Router.HandleFunc("/eth/v1/beacon/rewards/blocks/{block_id}", rewardsServer.BlockRewards).Methods(http.MethodGet)
|
||||||
@@ -304,6 +304,7 @@ func (s *Service) Start() {
|
|||||||
BlockBuilder: s.cfg.BlockBuilder,
|
BlockBuilder: s.cfg.BlockBuilder,
|
||||||
OperationNotifier: s.cfg.OperationNotifier,
|
OperationNotifier: s.cfg.OperationNotifier,
|
||||||
CoreService: coreService,
|
CoreService: coreService,
|
||||||
|
BlockRewardFetcher: rewardFetcher,
|
||||||
}
|
}
|
||||||
|
|
||||||
s.cfg.Router.HandleFunc("/eth/v1/validator/aggregate_attestation", validatorServerV1.GetAggregateAttestation).Methods(http.MethodGet)
|
s.cfg.Router.HandleFunc("/eth/v1/validator/aggregate_attestation", validatorServerV1.GetAggregateAttestation).Methods(http.MethodGet)
|
||||||
|
|||||||
@@ -73,7 +73,8 @@ func AttestingIndices(bf bitfield.Bitfield, committee []primitives.ValidatorInde
|
|||||||
return nil, fmt.Errorf("bitfield length %d is not equal to committee length %d", bf.Len(), len(committee))
|
return nil, fmt.Errorf("bitfield length %d is not equal to committee length %d", bf.Len(), len(committee))
|
||||||
}
|
}
|
||||||
indices := make([]uint64, 0, bf.Count())
|
indices := make([]uint64, 0, bf.Count())
|
||||||
for _, idx := range bf.BitIndices() {
|
p := bf.BitIndices()
|
||||||
|
for _, idx := range p {
|
||||||
if idx < len(committee) {
|
if idx < len(committee) {
|
||||||
indices = append(indices, uint64(committee[idx]))
|
indices = append(indices, uint64(committee[idx]))
|
||||||
}
|
}
|
||||||
@@ -104,6 +105,7 @@ func VerifyIndexedAttestationSig(ctx context.Context, indexedAtt *ethpb.IndexedA
|
|||||||
ctx, span := trace.StartSpan(ctx, "attestationutil.VerifyIndexedAttestationSig")
|
ctx, span := trace.StartSpan(ctx, "attestationutil.VerifyIndexedAttestationSig")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
indices := indexedAtt.AttestingIndices
|
indices := indexedAtt.AttestingIndices
|
||||||
|
|
||||||
messageHash, err := signing.ComputeSigningRoot(indexedAtt.Data, domain)
|
messageHash, err := signing.ComputeSigningRoot(indexedAtt.Data, domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "could not get signing root of object")
|
return errors.Wrap(err, "could not get signing root of object")
|
||||||
|
|||||||
Reference in New Issue
Block a user