Fix incorrect version used when sending attestation version in Fulu (#15950)

* Fix incorrect version used when sending attestation version in Fulu

* update typo

* fix Eth-Consensus-Version in submit_signed_aggregate_proof.go
This commit is contained in:
Muzry
2025-10-31 21:17:44 +08:00
committed by GitHub
parent 3e0492a636
commit 374bae9c81
5 changed files with 120 additions and 33 deletions

View File

@@ -0,0 +1,2 @@
### Fixed
- Fix incorrect version used when sending attestation version in Fulu

View File

@@ -10,6 +10,7 @@ import (
"github.com/OffchainLabs/prysm/v6/network/httputil"
ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1"
"github.com/OffchainLabs/prysm/v6/runtime/version"
"github.com/OffchainLabs/prysm/v6/time/slots"
"github.com/pkg/errors"
)
@@ -67,7 +68,8 @@ func (c *beaconApiValidatorClient) proposeAttestationElectra(ctx context.Context
if err != nil {
return nil, err
}
headers := map[string]string{"Eth-Consensus-Version": version.String(attestation.Version())}
consensusVersion := version.String(slots.ToForkVersion(attestation.Data.Slot))
headers := map[string]string{"Eth-Consensus-Version": consensusVersion}
if err = c.jsonRestHandler.Post(
ctx,
"/eth/v2/beacon/pool/attestations",

View File

@@ -8,11 +8,14 @@ import (
"testing"
"github.com/OffchainLabs/prysm/v6/beacon-chain/core/helpers"
"github.com/OffchainLabs/prysm/v6/config/params"
"github.com/OffchainLabs/prysm/v6/consensus-types/primitives"
"github.com/OffchainLabs/prysm/v6/network/httputil"
ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1"
"github.com/OffchainLabs/prysm/v6/runtime/version"
"github.com/OffchainLabs/prysm/v6/testing/assert"
"github.com/OffchainLabs/prysm/v6/testing/require"
"github.com/OffchainLabs/prysm/v6/time/slots"
"github.com/OffchainLabs/prysm/v6/validator/client/beacon-api/mock"
testhelpers "github.com/OffchainLabs/prysm/v6/validator/client/beacon-api/test-helpers"
"go.uber.org/mock/gomock"
@@ -214,36 +217,58 @@ func TestProposeAttestationFallBack(t *testing.T) {
}
func TestProposeAttestationElectra(t *testing.T) {
attestation := &ethpb.SingleAttestation{
AttesterIndex: 74,
Data: &ethpb.AttestationData{
Slot: 75,
CommitteeIndex: 76,
BeaconBlockRoot: testhelpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 78,
Root: testhelpers.FillByteSlice(32, 79),
params.SetupTestConfigCleanup(t)
params.BeaconConfig().ElectraForkEpoch = 0
params.BeaconConfig().FuluForkEpoch = 1
buildSingleAttestation := func(slot primitives.Slot) *ethpb.SingleAttestation {
targetEpoch := slots.ToEpoch(slot)
sourceEpoch := targetEpoch
if targetEpoch > 0 {
sourceEpoch = targetEpoch - 1
}
return &ethpb.SingleAttestation{
AttesterIndex: 74,
Data: &ethpb.AttestationData{
Slot: slot,
CommitteeIndex: 76,
BeaconBlockRoot: testhelpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: sourceEpoch,
Root: testhelpers.FillByteSlice(32, 79),
},
Target: &ethpb.Checkpoint{
Epoch: targetEpoch,
Root: testhelpers.FillByteSlice(32, 81),
},
},
Target: &ethpb.Checkpoint{
Epoch: 80,
Root: testhelpers.FillByteSlice(32, 81),
},
},
Signature: testhelpers.FillByteSlice(96, 82),
CommitteeId: 83,
Signature: testhelpers.FillByteSlice(96, 82),
CommitteeId: 83,
}
}
attestationElectra := buildSingleAttestation(0)
attestationFulu := buildSingleAttestation(params.BeaconConfig().SlotsPerEpoch)
tests := []struct {
name string
attestation *ethpb.SingleAttestation
expectedErrorMessage string
endpointError error
endpointCall int
name string
attestation *ethpb.SingleAttestation
expectedConsensusVersion string
expectedErrorMessage string
endpointError error
endpointCall int
}{
{
name: "valid",
attestation: attestation,
endpointCall: 1,
name: "valid electra",
attestation: attestationElectra,
expectedConsensusVersion: version.String(slots.ToForkVersion(attestationElectra.GetData().GetSlot())),
endpointCall: 1,
},
{
name: "valid fulu consensus version",
attestation: attestationFulu,
expectedConsensusVersion: version.String(slots.ToForkVersion(attestationFulu.GetData().GetSlot())),
endpointCall: 1,
},
{
name: "nil attestation",
@@ -283,8 +308,11 @@ func TestProposeAttestationElectra(t *testing.T) {
expectedErrorMessage: "attestation's target can't be nil",
},
{
name: "bad request",
attestation: attestation,
name: "bad request",
attestation: attestationElectra,
expectedConsensusVersion: version.String(
slots.ToForkVersion(attestationElectra.GetData().GetSlot()),
),
expectedErrorMessage: "bad request",
endpointError: errors.New("bad request"),
endpointCall: 1,
@@ -304,11 +332,14 @@ func TestProposeAttestationElectra(t *testing.T) {
}
ctx := t.Context()
headers := map[string]string{"Eth-Consensus-Version": version.String(test.attestation.Version())}
headerMatcher := gomock.Any()
if test.expectedConsensusVersion != "" {
headerMatcher = gomock.Eq(map[string]string{"Eth-Consensus-Version": test.expectedConsensusVersion})
}
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v2/beacon/pool/attestations",
headers,
headerMatcher,
bytes.NewBuffer(marshalledAttestations),
nil,
).Return(
@@ -325,7 +356,7 @@ func TestProposeAttestationElectra(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, proposeResponse)
expectedAttestationDataRoot, err := attestation.Data.HashTreeRoot()
expectedAttestationDataRoot, err := test.attestation.Data.HashTreeRoot()
require.NoError(t, err)
// Make sure that the attestation data root is set

View File

@@ -10,6 +10,7 @@ import (
"github.com/OffchainLabs/prysm/v6/network/httputil"
ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1"
"github.com/OffchainLabs/prysm/v6/runtime/version"
"github.com/OffchainLabs/prysm/v6/time/slots"
"github.com/pkg/errors"
)
@@ -54,7 +55,9 @@ func (c *beaconApiValidatorClient) submitSignedAggregateSelectionProofElectra(ct
if err != nil {
return nil, errors.Wrap(err, "failed to marshal SignedAggregateAttestationAndProofElectra")
}
headers := map[string]string{"Eth-Consensus-Version": version.String(in.SignedAggregateAndProof.Version())}
dataSlot := in.SignedAggregateAndProof.Message.Aggregate.Data.Slot
consensusVersion := version.String(slots.ToForkVersion(dataSlot))
headers := map[string]string{"Eth-Consensus-Version": consensusVersion}
if err = c.jsonRestHandler.Post(ctx, "/eth/v2/validator/aggregate_and_proofs", headers, bytes.NewBuffer(body), nil); err != nil {
return nil, err
}

View File

@@ -7,11 +7,13 @@ import (
"testing"
"github.com/OffchainLabs/prysm/v6/api/server/structs"
"github.com/OffchainLabs/prysm/v6/config/params"
"github.com/OffchainLabs/prysm/v6/network/httputil"
ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1"
"github.com/OffchainLabs/prysm/v6/runtime/version"
"github.com/OffchainLabs/prysm/v6/testing/assert"
"github.com/OffchainLabs/prysm/v6/testing/require"
"github.com/OffchainLabs/prysm/v6/time/slots"
"github.com/OffchainLabs/prysm/v6/validator/client/beacon-api/mock"
testhelpers "github.com/OffchainLabs/prysm/v6/validator/client/beacon-api/test-helpers"
"github.com/pkg/errors"
@@ -123,6 +125,10 @@ func TestSubmitSignedAggregateSelectionProof_Fallback(t *testing.T) {
}
func TestSubmitSignedAggregateSelectionProofElectra_Valid(t *testing.T) {
params.SetupTestConfigCleanup(t)
params.BeaconConfig().ElectraForkEpoch = 0
params.BeaconConfig().FuluForkEpoch = 100
ctrl := gomock.NewController(t)
defer ctrl.Finish()
@@ -131,7 +137,8 @@ func TestSubmitSignedAggregateSelectionProofElectra_Valid(t *testing.T) {
require.NoError(t, err)
ctx := t.Context()
headers := map[string]string{"Eth-Consensus-Version": version.String(signedAggregateAndProofElectra.Message.Version())}
expectedVersion := version.String(slots.ToForkVersion(signedAggregateAndProofElectra.Message.Aggregate.Data.Slot))
headers := map[string]string{"Eth-Consensus-Version": expectedVersion}
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
@@ -155,6 +162,10 @@ func TestSubmitSignedAggregateSelectionProofElectra_Valid(t *testing.T) {
}
func TestSubmitSignedAggregateSelectionProofElectra_BadRequest(t *testing.T) {
params.SetupTestConfigCleanup(t)
params.BeaconConfig().ElectraForkEpoch = 0
params.BeaconConfig().FuluForkEpoch = 100
ctrl := gomock.NewController(t)
defer ctrl.Finish()
@@ -163,7 +174,8 @@ func TestSubmitSignedAggregateSelectionProofElectra_BadRequest(t *testing.T) {
require.NoError(t, err)
ctx := t.Context()
headers := map[string]string{"Eth-Consensus-Version": version.String(signedAggregateAndProofElectra.Message.Version())}
expectedVersion := version.String(slots.ToForkVersion(signedAggregateAndProofElectra.Message.Aggregate.Data.Slot))
headers := map[string]string{"Eth-Consensus-Version": expectedVersion}
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
@@ -182,6 +194,43 @@ func TestSubmitSignedAggregateSelectionProofElectra_BadRequest(t *testing.T) {
assert.ErrorContains(t, "bad request", err)
}
func TestSubmitSignedAggregateSelectionProofElectra_FuluVersion(t *testing.T) {
params.SetupTestConfigCleanup(t)
params.BeaconConfig().ElectraForkEpoch = 0
params.BeaconConfig().FuluForkEpoch = 1
ctrl := gomock.NewController(t)
defer ctrl.Finish()
signedAggregateAndProofElectra := generateSignedAggregateAndProofElectraJson()
marshalledSignedAggregateSignedAndProofElectra, err := json.Marshal([]*structs.SignedAggregateAttestationAndProofElectra{jsonifySignedAggregateAndProofElectra(signedAggregateAndProofElectra)})
require.NoError(t, err)
ctx := t.Context()
expectedVersion := version.String(slots.ToForkVersion(signedAggregateAndProofElectra.Message.Aggregate.Data.Slot))
headers := map[string]string{"Eth-Consensus-Version": expectedVersion}
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v2/validator/aggregate_and_proofs",
headers,
bytes.NewBuffer(marshalledSignedAggregateSignedAndProofElectra),
nil,
).Return(
nil,
).Times(1)
attestationDataRoot, err := signedAggregateAndProofElectra.Message.Aggregate.Data.HashTreeRoot()
require.NoError(t, err)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
resp, err := validatorClient.submitSignedAggregateSelectionProofElectra(ctx, &ethpb.SignedAggregateSubmitElectraRequest{
SignedAggregateAndProof: signedAggregateAndProofElectra,
})
require.NoError(t, err)
assert.DeepEqual(t, attestationDataRoot[:], resp.AttestationDataRoot)
}
func generateSignedAggregateAndProofJson() *ethpb.SignedAggregateAttestationAndProof {
return &ethpb.SignedAggregateAttestationAndProof{
Message: &ethpb.AggregateAttestationAndProof{