fixing web3signer for e2e (#15832)

* fixing web3signer for e2e

* fixing tests

* gaz

* reverting fix

* extra space
This commit is contained in:
james-prysm
2025-10-09 14:21:56 -05:00
committed by GitHub
parent 515590e7fe
commit c0ad87df4b
8 changed files with 131 additions and 35 deletions

View File

@@ -8,6 +8,8 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//config/fieldparams:go_default_library",
"//config/params:go_default_library",
"//consensus-types/primitives:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//proto/prysm/v1alpha1/validator-client:go_default_library",
"//runtime/version:go_default_library",

View File

@@ -1,10 +1,13 @@
package mock
import (
"encoding/json"
"fmt"
"strings"
fieldparams "github.com/OffchainLabs/prysm/v6/config/fieldparams"
"github.com/OffchainLabs/prysm/v6/config/params"
"github.com/OffchainLabs/prysm/v6/consensus-types/primitives"
eth "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1"
validatorpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1/validator-client"
"github.com/OffchainLabs/prysm/v6/runtime/version"
@@ -55,6 +58,32 @@ func GetMockSignRequest(t string) *validatorpb.SignRequest {
},
SigningSlot: 0,
}
case "AGGREGATE_AND_PROOF":
return &validatorpb.SignRequest{
PublicKey: make([]byte, fieldparams.BLSPubkeyLength),
SigningRoot: make([]byte, fieldparams.RootLength),
SignatureDomain: make([]byte, 4),
Object: &validatorpb.SignRequest_AggregateAttestationAndProof{
AggregateAttestationAndProof: &eth.AggregateAttestationAndProof{
AggregatorIndex: 0,
Aggregate: &eth.Attestation{
AggregationBits: bitfield.Bitlist{0b1101},
Data: &eth.AttestationData{
BeaconBlockRoot: make([]byte, fieldparams.RootLength),
Source: &eth.Checkpoint{
Root: make([]byte, fieldparams.RootLength),
},
Target: &eth.Checkpoint{
Root: make([]byte, fieldparams.RootLength),
},
},
Signature: make([]byte, 96),
},
SelectionProof: make([]byte, fieldparams.BLSSignatureLength),
},
},
SigningSlot: 0,
}
case "AGGREGATE_AND_PROOF_V2":
committeeBits := bitfield.NewBitvector64()
committeeBits.SetBitAt(0, true)
@@ -82,7 +111,7 @@ func GetMockSignRequest(t string) *validatorpb.SignRequest {
SelectionProof: make([]byte, fieldparams.BLSSignatureLength),
},
},
SigningSlot: 0,
SigningSlot: primitives.Slot(params.BeaconConfig().ElectraForkEpoch) * primitives.Slot(params.BeaconConfig().SlotsPerEpoch),
}
case "ATTESTATION":
return &validatorpb.SignRequest{
@@ -521,17 +550,34 @@ func AggregationSlotSignRequest() *types.AggregationSlotSignRequest {
// AggregateAndProofV2SignRequest is a mock implementation of the AggregateAndProofV2SignRequest.
func AggregateAndProofV2SignRequest(ver int) *types.AggregateAndProofV2SignRequest {
var aggregateAndProofJSON []byte
var slot primitives.Slot
if ver < version.Electra {
aggregateAndProofData := &types.AggregateAndProof{
AggregatorIndex: "0",
Aggregate: Attestation(),
SelectionProof: make([]byte, fieldparams.BLSSignatureLength),
}
aggregateAndProofJSON, _ = json.Marshal(aggregateAndProofData)
slot = 0 // Pre-Electra slot
} else {
aggregateAndProofData := &types.AggregateAndProofElectra{
AggregatorIndex: "0",
Aggregate: AttestationElectra(),
SelectionProof: make([]byte, fieldparams.BLSSignatureLength),
}
aggregateAndProofJSON, _ = json.Marshal(aggregateAndProofData)
slot = primitives.Slot(params.BeaconConfig().ElectraForkEpoch) * primitives.Slot(params.BeaconConfig().SlotsPerEpoch)
}
// Generate ForkInfo dynamically based on the slot
forkInfo, _ := types.MapForkInfo(slot, make([]byte, fieldparams.RootLength))
return &types.AggregateAndProofV2SignRequest{
Type: "AGGREGATE_AND_PROOF_V2",
ForkInfo: ForkInfo(),
ForkInfo: forkInfo,
SigningRoot: make([]byte, fieldparams.RootLength),
AggregateAndProof: &types.AggregateAndProofV2{
Version: strings.ToUpper(version.String(ver)),
Data: &types.AggregateAndProofElectra{
AggregatorIndex: "0",
Aggregate: AttestationElectra(),
SelectionProof: make([]byte, fieldparams.BLSSignatureLength),
},
Data: aggregateAndProofJSON,
},
}
}

View File

@@ -1,6 +1,7 @@
package types
import (
"encoding/json"
"fmt"
"strings"
@@ -67,28 +68,53 @@ func GetAggregationSlotSignRequest(request *validatorpb.SignRequest, genesisVali
// GetAggregateAndProofV2SignRequest maps the request for signing type AGGREGATE_AND_PROOF_V2 on Electra changes.
func GetAggregateAndProofV2SignRequest(v int, request *validatorpb.SignRequest, genesisValidatorsRoot []byte) (*AggregateAndProofV2SignRequest, error) {
aggregateAttestationAndProof, ok := request.Object.(*validatorpb.SignRequest_AggregateAttestationAndProofElectra)
if !ok {
return nil, errors.New("failed to cast request object to aggregate attestation and proof")
}
if aggregateAttestationAndProof == nil {
return nil, errors.New("invalid sign request: AggregateAndProof is nil")
}
fork, err := MapForkInfo(request.SigningSlot, genesisValidatorsRoot)
if err != nil {
return nil, err
}
aggregateAndProof, err := MapAggregateAndProofElectra(aggregateAttestationAndProof.AggregateAttestationAndProofElectra)
if err != nil {
return nil, err
var aggregateAndProofJSON []byte
if v < version.Electra {
aggregateAttestationAndProof, ok := request.Object.(*validatorpb.SignRequest_AggregateAttestationAndProof)
if !ok {
return nil, errors.New("failed to cast request object to aggregate attestation and proof")
}
if aggregateAttestationAndProof == nil {
return nil, errors.New("invalid sign request: AggregateAndProof is nil")
}
aggregateAndProof, err := MapAggregateAndProof(aggregateAttestationAndProof.AggregateAttestationAndProof)
if err != nil {
return nil, err
}
aggregateAndProofJSON, err = json.Marshal(aggregateAndProof)
if err != nil {
return nil, err
}
} else {
aggregateAttestationAndProof, ok := request.Object.(*validatorpb.SignRequest_AggregateAttestationAndProofElectra)
if !ok {
return nil, errors.New("failed to cast request object to aggregate attestation and proof Electra")
}
if aggregateAttestationAndProof == nil {
return nil, errors.New("invalid sign request: AggregateAndProof is nil")
}
aggregateAndProof, err := MapAggregateAndProofElectra(aggregateAttestationAndProof.AggregateAttestationAndProofElectra)
if err != nil {
return nil, err
}
aggregateAndProofJSON, err = json.Marshal(aggregateAndProof)
if err != nil {
return nil, err
}
}
return &AggregateAndProofV2SignRequest{
Type: "AGGREGATE_AND_PROOF_V2",
ForkInfo: fork,
SigningRoot: request.SigningRoot,
AggregateAndProof: &AggregateAndProofV2{
Version: strings.ToUpper(version.String(v)),
Data: aggregateAndProof,
Data: aggregateAndProofJSON,
},
}, nil
}

View File

@@ -1,6 +1,7 @@
package types_test
import (
"encoding/json"
"reflect"
"testing"
@@ -15,6 +16,7 @@ import (
func TestGetAggregateAndProofV2SignRequest(t *testing.T) {
type args struct {
version int
request *validatorpb.SignRequest
genesisValidatorsRoot []byte
}
@@ -25,24 +27,40 @@ func TestGetAggregateAndProofV2SignRequest(t *testing.T) {
wantErr bool
}{
{
name: "Happy Path Test",
name: "Happy Path Test Electra",
args: args{
version: version.Electra,
request: mock.GetMockSignRequest("AGGREGATE_AND_PROOF_V2"),
genesisValidatorsRoot: make([]byte, fieldparams.RootLength),
},
want: mock.AggregateAndProofV2SignRequest(version.Electra),
wantErr: false,
},
{
name: "Happy Path Test Pre-Electra",
args: args{
version: version.Deneb,
request: mock.GetMockSignRequest("AGGREGATE_AND_PROOF"),
genesisValidatorsRoot: make([]byte, fieldparams.RootLength),
},
want: mock.AggregateAndProofV2SignRequest(version.Deneb),
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := types.GetAggregateAndProofV2SignRequest(version.Electra, tt.args.request, tt.args.genesisValidatorsRoot)
got, err := types.GetAggregateAndProofV2SignRequest(tt.args.version, tt.args.request, tt.args.genesisValidatorsRoot)
if (err != nil) != tt.wantErr {
t.Errorf("GetAggregateAndProofV2SignRequest() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("GetAggregateAndProofV2SignRequest() got = %v, want %v", got, tt.want)
// Marshal to JSON for comparison since ForkInfo is generated dynamically
gotJSON, err := json.Marshal(got)
require.NoError(t, err)
wantJSON, err := json.Marshal(tt.want)
require.NoError(t, err)
if string(gotJSON) != string(wantJSON) {
t.Errorf("JSON mismatch:\ngot: %s\nwant: %s", string(gotJSON), string(wantJSON))
}
})
}

View File

@@ -3,6 +3,8 @@
package types
import (
"encoding/json"
"github.com/ethereum/go-ethereum/common/hexutil"
)
@@ -32,8 +34,8 @@ type AggregateAndProofV2SignRequest struct {
// AggregateAndProofV2 is a wrapper object for AggregateAndProofV2SignRequest
type AggregateAndProofV2 struct {
Version string `json:"version" validate:"required"`
Data *AggregateAndProofElectra `json:"data" validate:"required"` // specifies Electra for now
Version string `json:"version" validate:"required"`
Data json.RawMessage `json:"data" validate:"required"`
}
// AttestationSignRequest is a request object for web3signer sign api.