From 4d823acf453e77a4e9c6504b4732895f784f3da2 Mon Sep 17 00:00:00 2001 From: james-prysm <90280386+james-prysm@users.noreply.github.com> Date: Mon, 22 Jul 2024 17:31:12 -0500 Subject: [PATCH] moving cloners to attestation.go and adding fuzzing (#14254) * moving cloners to attestation.go and adding fuzzing * fixing bazel * fixing build --- .../blockchain/process_attestation.go | 2 +- .../operations/attestations/kv/aggregated.go | 2 +- .../operations/attestations/kv/block.go | 2 +- .../operations/attestations/kv/forkchoice.go | 2 +- .../attestations/kv/unaggregated.go | 2 +- .../attestations/prepare_forkchoice.go | 2 +- .../rpc/prysm/v1alpha1/validator/attester.go | 4 +- .../validator/proposer_utils_bench_test.go | 2 +- .../state/state-native/getters_attestation.go | 20 +- .../state/state-native/getters_checkpoint.go | 6 +- .../state/state-native/references_test.go | 4 +- proto/prysm/v1alpha1/BUILD.bazel | 4 + proto/prysm/v1alpha1/attestation.go | 131 ++++++++++- .../aggregation/attestations/attestations.go | 4 +- .../aggregation/attestations/maxcover.go | 4 +- proto/prysm/v1alpha1/attestation_fuzz_test.go | 38 +++ proto/prysm/v1alpha1/cloners.go | 216 +++--------------- proto/prysm/v1alpha1/cloners_test.go | 107 +-------- proto/prysm/v1alpha1/export_test.go | 3 + 19 files changed, 239 insertions(+), 316 deletions(-) create mode 100644 proto/prysm/v1alpha1/attestation_fuzz_test.go create mode 100644 proto/prysm/v1alpha1/export_test.go diff --git a/beacon-chain/blockchain/process_attestation.go b/beacon-chain/blockchain/process_attestation.go index 19d2abd46c75..d4bd636b7783 100644 --- a/beacon-chain/blockchain/process_attestation.go +++ b/beacon-chain/blockchain/process_attestation.go @@ -46,7 +46,7 @@ func (s *Service) OnAttestation(ctx context.Context, a ethpb.Att, disparity time if err := helpers.ValidateSlotTargetEpoch(a.GetData()); err != nil { return err } - tgt := ethpb.CopyCheckpoint(a.GetData().Target) + tgt := a.GetData().Target.Copy() // Note that target root check is ignored here because it was performed in sync's validation pipeline: // validate_aggregate_proof.go and validate_beacon_attestation.go diff --git a/beacon-chain/operations/attestations/kv/aggregated.go b/beacon-chain/operations/attestations/kv/aggregated.go index 24a19e41d888..8d6081f280e3 100644 --- a/beacon-chain/operations/attestations/kv/aggregated.go +++ b/beacon-chain/operations/attestations/kv/aggregated.go @@ -145,7 +145,7 @@ func (c *AttCaches) SaveAggregatedAttestation(att ethpb.Att) error { if err != nil { return errors.Wrap(err, "could not create attestation ID") } - copiedAtt := att.Copy() + copiedAtt := att.Clone() c.aggregatedAttLock.Lock() defer c.aggregatedAttLock.Unlock() diff --git a/beacon-chain/operations/attestations/kv/block.go b/beacon-chain/operations/attestations/kv/block.go index 08d6f7ed90df..5f675bfad201 100644 --- a/beacon-chain/operations/attestations/kv/block.go +++ b/beacon-chain/operations/attestations/kv/block.go @@ -33,7 +33,7 @@ func (c *AttCaches) SaveBlockAttestation(att ethpb.Att) error { } } - c.blockAtt[id] = append(atts, att.Copy()) + c.blockAtt[id] = append(atts, att.Clone()) return nil } diff --git a/beacon-chain/operations/attestations/kv/forkchoice.go b/beacon-chain/operations/attestations/kv/forkchoice.go index 609d55f64c50..26bb0634ccbd 100644 --- a/beacon-chain/operations/attestations/kv/forkchoice.go +++ b/beacon-chain/operations/attestations/kv/forkchoice.go @@ -42,7 +42,7 @@ func (c *AttCaches) ForkchoiceAttestations() []ethpb.Att { atts := make([]ethpb.Att, 0, len(c.forkchoiceAtt)) for _, att := range c.forkchoiceAtt { - atts = append(atts, att.Copy()) + atts = append(atts, att.Clone()) } return atts diff --git a/beacon-chain/operations/attestations/kv/unaggregated.go b/beacon-chain/operations/attestations/kv/unaggregated.go index 8ec2d171f49b..f49f666b561f 100644 --- a/beacon-chain/operations/attestations/kv/unaggregated.go +++ b/beacon-chain/operations/attestations/kv/unaggregated.go @@ -64,7 +64,7 @@ func (c *AttCaches) UnaggregatedAttestations() ([]ethpb.Att, error) { return nil, err } if !seen { - atts = append(atts, att.Copy()) + atts = append(atts, att.Clone()) } } return atts, nil diff --git a/beacon-chain/operations/attestations/prepare_forkchoice.go b/beacon-chain/operations/attestations/prepare_forkchoice.go index 38b69b9583dc..7eef4065c62f 100644 --- a/beacon-chain/operations/attestations/prepare_forkchoice.go +++ b/beacon-chain/operations/attestations/prepare_forkchoice.go @@ -106,7 +106,7 @@ func (s *Service) batchForkChoiceAtts(ctx context.Context) error { func (s *Service) aggregateAndSaveForkChoiceAtts(atts []ethpb.Att) error { clonedAtts := make([]ethpb.Att, len(atts)) for i, a := range atts { - clonedAtts[i] = a.Copy() + clonedAtts[i] = a.Clone() } aggregatedAtts, err := attaggregation.Aggregate(clonedAtts) if err != nil { diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/attester.go b/beacon-chain/rpc/prysm/v1alpha1/validator/attester.go index 2f0342c36e99..26ab6d7c7586 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/attester.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/attester.go @@ -50,7 +50,7 @@ func (vs *Server) ProposeAttestation(ctx context.Context, att *ethpb.Attestation } go func() { - attCopy := ethpb.CopyAttestation(att) + attCopy := att.Copy() if err := vs.AttPool.SaveUnaggregatedAttestation(attCopy); err != nil { log.WithError(err).Error("Could not save unaggregated attestation") return @@ -84,7 +84,7 @@ func (vs *Server) ProposeAttestationElectra(ctx context.Context, att *ethpb.Atte go func() { ctx = trace.NewContext(context.Background(), trace.FromContext(ctx)) - attCopy := ethpb.CopyAttestationElectra(att) + attCopy := att.Copy() if err := vs.AttPool.SaveUnaggregatedAttestation(attCopy); err != nil { log.WithError(err).Error("Could not save unaggregated attestation") return diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_utils_bench_test.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_utils_bench_test.go index c88b97a645e5..d1407a9b7b86 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_utils_bench_test.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_utils_bench_test.go @@ -47,7 +47,7 @@ func BenchmarkProposerAtts_sortByProfitability(b *testing.B) { runner := func(atts []ethpb.Att) { attsCopy := make(proposerAtts, len(atts)) for i, att := range atts { - attsCopy[i] = ethpb.CopyAttestation(att.(*ethpb.Attestation)) + attsCopy[i] = att.(*ethpb.Attestation).Copy() } _, err := attsCopy.sortByProfitability() require.NoError(b, err, "Could not sort attestations by profitability") diff --git a/beacon-chain/state/state-native/getters_attestation.go b/beacon-chain/state/state-native/getters_attestation.go index dcc387d0b11c..0139313018e1 100644 --- a/beacon-chain/state/state-native/getters_attestation.go +++ b/beacon-chain/state/state-native/getters_attestation.go @@ -24,7 +24,15 @@ func (b *BeaconState) PreviousEpochAttestations() ([]*ethpb.PendingAttestation, // previousEpochAttestationsVal corresponding to blocks on the beacon chain. // This assumes that a lock is already held on BeaconState. func (b *BeaconState) previousEpochAttestationsVal() []*ethpb.PendingAttestation { - return ethpb.CopyPendingAttestationSlice(b.previousEpochAttestations) + if b.previousEpochAttestations == nil { + return nil + } + + res := make([]*ethpb.PendingAttestation, len(b.previousEpochAttestations)) + for i := 0; i < len(res); i++ { + res[i] = b.previousEpochAttestations[i].Copy() + } + return res } // CurrentEpochAttestations corresponding to blocks on the beacon chain. @@ -46,5 +54,13 @@ func (b *BeaconState) CurrentEpochAttestations() ([]*ethpb.PendingAttestation, e // currentEpochAttestations corresponding to blocks on the beacon chain. // This assumes that a lock is already held on BeaconState. func (b *BeaconState) currentEpochAttestationsVal() []*ethpb.PendingAttestation { - return ethpb.CopyPendingAttestationSlice(b.currentEpochAttestations) + if b.currentEpochAttestations == nil { + return nil + } + + res := make([]*ethpb.PendingAttestation, len(b.currentEpochAttestations)) + for i := 0; i < len(res); i++ { + res[i] = b.currentEpochAttestations[i].Copy() + } + return res } diff --git a/beacon-chain/state/state-native/getters_checkpoint.go b/beacon-chain/state/state-native/getters_checkpoint.go index e7f753f16ede..a592f747a0be 100644 --- a/beacon-chain/state/state-native/getters_checkpoint.go +++ b/beacon-chain/state/state-native/getters_checkpoint.go @@ -47,7 +47,7 @@ func (b *BeaconState) PreviousJustifiedCheckpoint() *ethpb.Checkpoint { // previousJustifiedCheckpointVal denoting an epoch and block root. // This assumes that a lock is already held on BeaconState. func (b *BeaconState) previousJustifiedCheckpointVal() *ethpb.Checkpoint { - return ethpb.CopyCheckpoint(b.previousJustifiedCheckpoint) + return b.previousJustifiedCheckpoint.Copy() } // CurrentJustifiedCheckpoint denoting an epoch and block root. @@ -65,7 +65,7 @@ func (b *BeaconState) CurrentJustifiedCheckpoint() *ethpb.Checkpoint { // currentJustifiedCheckpointVal denoting an epoch and block root. // This assumes that a lock is already held on BeaconState. func (b *BeaconState) currentJustifiedCheckpointVal() *ethpb.Checkpoint { - return ethpb.CopyCheckpoint(b.currentJustifiedCheckpoint) + return b.currentJustifiedCheckpoint.Copy() } // MatchCurrentJustifiedCheckpoint returns true if input justified checkpoint matches @@ -109,7 +109,7 @@ func (b *BeaconState) FinalizedCheckpoint() *ethpb.Checkpoint { // finalizedCheckpointVal denoting an epoch and block root. // This assumes that a lock is already held on BeaconState. func (b *BeaconState) finalizedCheckpointVal() *ethpb.Checkpoint { - return ethpb.CopyCheckpoint(b.finalizedCheckpoint) + return b.finalizedCheckpoint.Copy() } // FinalizedCheckpointEpoch returns the epoch value of the finalized checkpoint. diff --git a/beacon-chain/state/state-native/references_test.go b/beacon-chain/state/state-native/references_test.go index 95066efb50e3..82596e11ccf3 100644 --- a/beacon-chain/state/state-native/references_test.go +++ b/beacon-chain/state/state-native/references_test.go @@ -789,7 +789,7 @@ func TestStateReferenceCopy_NoUnexpectedAttestationsMutation(t *testing.T) { currEpochAtts, err = state.CurrentEpochAttestations() require.NoError(t, err) for i := range currEpochAtts { - att := ethpb.CopyPendingAttestation(currEpochAtts[i]) + att := currEpochAtts[i].Copy() att.AggregationBits = bitfield.NewBitlist(3) currEpochAtts[i] = att } @@ -803,7 +803,7 @@ func TestStateReferenceCopy_NoUnexpectedAttestationsMutation(t *testing.T) { prevEpochAtts, err = state.PreviousEpochAttestations() require.NoError(t, err) for i := range prevEpochAtts { - att := ethpb.CopyPendingAttestation(prevEpochAtts[i]) + att := prevEpochAtts[i].Copy() att.AggregationBits = bitfield.NewBitlist(3) prevEpochAtts[i] = att } diff --git a/proto/prysm/v1alpha1/BUILD.bazel b/proto/prysm/v1alpha1/BUILD.bazel index 75b3b0cfd48f..2acb80cafeec 100644 --- a/proto/prysm/v1alpha1/BUILD.bazel +++ b/proto/prysm/v1alpha1/BUILD.bazel @@ -371,10 +371,14 @@ ssz_proto_files( go_test( name = "go_default_test", srcs = [ + "attestation_fuzz_test.go", "cloners_test.go", + "export_test.go", ], embed = [":go_default_library"], deps = [ "//testing/assert:go_default_library", + "//testing/require:go_default_library", + "@com_github_google_gofuzz//:go_default_library", ], ) diff --git a/proto/prysm/v1alpha1/attestation.go b/proto/prysm/v1alpha1/attestation.go index 92b7f146ddef..d59d2cfcdb5d 100644 --- a/proto/prysm/v1alpha1/attestation.go +++ b/proto/prysm/v1alpha1/attestation.go @@ -4,6 +4,7 @@ import ( ssz "github.com/prysmaticlabs/fastssz" "github.com/prysmaticlabs/go-bitfield" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" + "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" "github.com/prysmaticlabs/prysm/v5/runtime/version" "google.golang.org/protobuf/proto" ) @@ -15,7 +16,7 @@ type Att interface { ssz.Unmarshaler ssz.HashRoot Version() int - Copy() Att + Clone() Att GetAggregationBits() bitfield.Bitlist GetData() *AttestationData CommitteeBitsVal() bitfield.Bitfield @@ -68,14 +69,51 @@ type AttSlashing interface { SecondAttestation() IndexedAtt } +// Copy -- +func (cp *Checkpoint) Copy() *Checkpoint { + if cp == nil { + return nil + } + return &Checkpoint{ + Epoch: cp.Epoch, + Root: bytesutil.SafeCopyBytes(cp.Root), + } +} + +// Copy -- +func (attData *AttestationData) Copy() *AttestationData { + if attData == nil { + return nil + } + return &AttestationData{ + Slot: attData.Slot, + CommitteeIndex: attData.CommitteeIndex, + BeaconBlockRoot: bytesutil.SafeCopyBytes(attData.BeaconBlockRoot), + Source: attData.Source.Copy(), + Target: attData.Target.Copy(), + } +} + // Version -- func (a *Attestation) Version() int { return version.Phase0 } +// Clone -- +func (a *Attestation) Clone() Att { + return a.Copy() +} + // Copy -- -func (a *Attestation) Copy() Att { - return CopyAttestation(a) +func (att *Attestation) Copy() *Attestation { + if att == nil { + return nil + } + return &Attestation{ + AggregationBits: bytesutil.SafeCopyBytes(att.AggregationBits), + Data: att.Data.Copy(), + Signature: bytesutil.SafeCopyBytes(att.Signature), + } } // CommitteeBitsVal -- @@ -90,9 +128,22 @@ func (a *PendingAttestation) Version() int { return version.Phase0 } +// Clone -- +func (a *PendingAttestation) Clone() Att { + return a.Copy() +} + // Copy -- -func (a *PendingAttestation) Copy() Att { - return CopyPendingAttestation(a) +func (a *PendingAttestation) Copy() *PendingAttestation { + if a == nil { + return nil + } + return &PendingAttestation{ + AggregationBits: bytesutil.SafeCopyBytes(a.AggregationBits), + Data: a.Data.Copy(), + InclusionDelay: a.InclusionDelay, + ProposerIndex: a.ProposerIndex, + } } // CommitteeBitsVal -- @@ -110,9 +161,22 @@ func (a *AttestationElectra) Version() int { return version.Electra } +// Clone -- +func (a *AttestationElectra) Clone() Att { + return a.Copy() +} + // Copy -- -func (a *AttestationElectra) Copy() Att { - return CopyAttestationElectra(a) +func (att *AttestationElectra) Copy() *AttestationElectra { + if att == nil { + return nil + } + return &AttestationElectra{ + AggregationBits: bytesutil.SafeCopyBytes(att.AggregationBits), + CommitteeBits: bytesutil.SafeCopyBytes(att.CommitteeBits), + Data: att.Data.Copy(), + Signature: bytesutil.SafeCopyBytes(att.Signature), + } } // CommitteeBitsVal -- @@ -130,6 +194,38 @@ func (a *IndexedAttestationElectra) Version() int { return version.Electra } +// Copy -- +func (indexedAtt *IndexedAttestation) Copy() *IndexedAttestation { + var indices []uint64 + if indexedAtt == nil { + return nil + } else if indexedAtt.AttestingIndices != nil { + indices = make([]uint64, len(indexedAtt.AttestingIndices)) + copy(indices, indexedAtt.AttestingIndices) + } + return &IndexedAttestation{ + AttestingIndices: indices, + Data: indexedAtt.Data.Copy(), + Signature: bytesutil.SafeCopyBytes(indexedAtt.Signature), + } +} + +// Copy -- +func (indexedAtt *IndexedAttestationElectra) Copy() *IndexedAttestationElectra { + var indices []uint64 + if indexedAtt == nil { + return nil + } else if indexedAtt.AttestingIndices != nil { + indices = make([]uint64, len(indexedAtt.AttestingIndices)) + copy(indices, indexedAtt.AttestingIndices) + } + return &IndexedAttestationElectra{ + AttestingIndices: indices, + Data: indexedAtt.Data.Copy(), + Signature: bytesutil.SafeCopyBytes(indexedAtt.Signature), + } +} + // Version -- func (a *AttesterSlashing) Version() int { return version.Phase0 @@ -160,6 +256,27 @@ func (a *AttesterSlashingElectra) SecondAttestation() IndexedAtt { return a.Attestation_2 } +func (a *AttesterSlashing) Copy() *AttesterSlashing { + if a == nil { + return nil + } + return &AttesterSlashing{ + Attestation_1: a.Attestation_1.Copy(), + Attestation_2: a.Attestation_2.Copy(), + } +} + +// Copy -- +func (a *AttesterSlashingElectra) Copy() *AttesterSlashingElectra { + if a == nil { + return nil + } + return &AttesterSlashingElectra{ + Attestation_1: a.Attestation_1.Copy(), + Attestation_2: a.Attestation_2.Copy(), + } +} + // Version -- func (a *AggregateAttestationAndProof) Version() int { return version.Phase0 diff --git a/proto/prysm/v1alpha1/attestation/aggregation/attestations/attestations.go b/proto/prysm/v1alpha1/attestation/aggregation/attestations/attestations.go index 8828687d8149..3f192d372bf6 100644 --- a/proto/prysm/v1alpha1/attestation/aggregation/attestations/attestations.go +++ b/proto/prysm/v1alpha1/attestation/aggregation/attestations/attestations.go @@ -83,8 +83,8 @@ func AggregatePair(a1, a2 *ethpb.Attestation) (*ethpb.Attestation, error) { return nil, aggregation.ErrBitsOverlap } - baseAtt := ethpb.CopyAttestation(a1) - newAtt := ethpb.CopyAttestation(a2) + baseAtt := a1.Copy() + newAtt := a2.Copy() if newAtt.AggregationBits.Count() > baseAtt.AggregationBits.Count() { baseAtt, newAtt = newAtt, baseAtt } diff --git a/proto/prysm/v1alpha1/attestation/aggregation/attestations/maxcover.go b/proto/prysm/v1alpha1/attestation/aggregation/attestations/maxcover.go index 7a95728b5802..2c1e6ea582c8 100644 --- a/proto/prysm/v1alpha1/attestation/aggregation/attestations/maxcover.go +++ b/proto/prysm/v1alpha1/attestation/aggregation/attestations/maxcover.go @@ -135,7 +135,7 @@ func (al attList) aggregate(coverage bitfield.Bitlist) (*ethpb.Attestation, erro } return ðpb.Attestation{ AggregationBits: coverage, - Data: ethpb.CopyAttestationData(al[0].GetData()), + Data: al[0].GetData().Copy(), Signature: aggregateSignatures(signs).Marshal(), }, nil } @@ -167,7 +167,7 @@ func aggregateAttestations(atts []ethpb.Att, keys []int, coverage *bitfield.Bitl } signs = append(signs, sig) if i == 0 { - data = ethpb.CopyAttestationData(atts[idx].GetData()) + data = atts[idx].GetData().Copy() targetIdx = idx } } diff --git a/proto/prysm/v1alpha1/attestation_fuzz_test.go b/proto/prysm/v1alpha1/attestation_fuzz_test.go new file mode 100644 index 000000000000..1334d0b62f51 --- /dev/null +++ b/proto/prysm/v1alpha1/attestation_fuzz_test.go @@ -0,0 +1,38 @@ +package eth_test + +import ( + "fmt" + "testing" + + fuzz "github.com/google/gofuzz" + eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/v5/testing/require" +) + +func TestCopyExecutionPayloadHeader_Fuzz(t *testing.T) { + fuzzCopies(t, ð.Checkpoint{}) + fuzzCopies(t, ð.AttestationData{}) + fuzzCopies(t, ð.Attestation{}) + fuzzCopies(t, ð.AttestationElectra{}) + fuzzCopies(t, ð.PendingAttestation{}) + fuzzCopies(t, ð.IndexedAttestation{}) + fuzzCopies(t, ð.IndexedAttestationElectra{}) + fuzzCopies(t, ð.AttesterSlashing{}) + fuzzCopies(t, ð.AttesterSlashingElectra{}) +} + +func fuzzCopies[T any, C eth.Copier[T]](t *testing.T, obj C) { + fuzzer := fuzz.NewWithSeed(0) + amount := 1000 + t.Run(fmt.Sprintf("%T", obj), func(t *testing.T) { + for i := 0; i < amount; i++ { + fuzzer.Fuzz(obj) // Populate thing with random values + got := obj.Copy() + require.DeepEqual(t, obj, got) + // check shallow copy working + fuzzer.Fuzz(got) + require.DeepNotEqual(t, obj, got) + // TODO: think of deeper not equal fuzzing + } + }) +} diff --git a/proto/prysm/v1alpha1/cloners.go b/proto/prysm/v1alpha1/cloners.go index f8c4610ccf42..b5a1517f7872 100644 --- a/proto/prysm/v1alpha1/cloners.go +++ b/proto/prysm/v1alpha1/cloners.go @@ -4,6 +4,19 @@ import ( "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" ) +type copier[T any] interface { + Copy() T +} + +func copySlice[T any, C copier[T]](original []C) []T { + // Create a new slice with the same length as the original + newSlice := make([]T, len(original)) + for i := 0; i < len(newSlice); i++ { + newSlice[i] = original[i].Copy() + } + return newSlice +} + // CopyETH1Data copies the provided eth1data object. func CopyETH1Data(data *Eth1Data) *Eth1Data { if data == nil { @@ -16,83 +29,6 @@ func CopyETH1Data(data *Eth1Data) *Eth1Data { } } -// CopyPendingAttestationSlice copies the provided slice of pending attestation objects. -func CopyPendingAttestationSlice(input []*PendingAttestation) []*PendingAttestation { - if input == nil { - return nil - } - - res := make([]*PendingAttestation, len(input)) - for i := 0; i < len(res); i++ { - res[i] = CopyPendingAttestation(input[i]) - } - return res -} - -// CopyPendingAttestation copies the provided pending attestation object. -func CopyPendingAttestation(att *PendingAttestation) *PendingAttestation { - if att == nil { - return nil - } - data := CopyAttestationData(att.Data) - return &PendingAttestation{ - AggregationBits: bytesutil.SafeCopyBytes(att.AggregationBits), - Data: data, - InclusionDelay: att.InclusionDelay, - ProposerIndex: att.ProposerIndex, - } -} - -// CopyAttestation copies the provided attestation object. -func CopyAttestation(att *Attestation) *Attestation { - if att == nil { - return nil - } - return &Attestation{ - AggregationBits: bytesutil.SafeCopyBytes(att.AggregationBits), - Data: CopyAttestationData(att.Data), - Signature: bytesutil.SafeCopyBytes(att.Signature), - } -} - -// CopyAttestationElectra copies the provided attestation object. -func CopyAttestationElectra(att *AttestationElectra) *AttestationElectra { - if att == nil { - return nil - } - return &AttestationElectra{ - AggregationBits: bytesutil.SafeCopyBytes(att.AggregationBits), - CommitteeBits: bytesutil.SafeCopyBytes(att.CommitteeBits), - Data: CopyAttestationData(att.Data), - Signature: bytesutil.SafeCopyBytes(att.Signature), - } -} - -// CopyAttestationData copies the provided AttestationData object. -func CopyAttestationData(attData *AttestationData) *AttestationData { - if attData == nil { - return nil - } - return &AttestationData{ - Slot: attData.Slot, - CommitteeIndex: attData.CommitteeIndex, - BeaconBlockRoot: bytesutil.SafeCopyBytes(attData.BeaconBlockRoot), - Source: CopyCheckpoint(attData.Source), - Target: CopyCheckpoint(attData.Target), - } -} - -// CopyCheckpoint copies the provided checkpoint. -func CopyCheckpoint(cp *Checkpoint) *Checkpoint { - if cp == nil { - return nil - } - return &Checkpoint{ - Epoch: cp.Epoch, - Root: bytesutil.SafeCopyBytes(cp.Root), - } -} - // CopySignedBeaconBlock copies the provided SignedBeaconBlock. func CopySignedBeaconBlock(sigBlock *SignedBeaconBlock) *SignedBeaconBlock { if sigBlock == nil { @@ -128,8 +64,8 @@ func CopyBeaconBlockBody(body *BeaconBlockBody) *BeaconBlockBody { Eth1Data: CopyETH1Data(body.Eth1Data), Graffiti: bytesutil.SafeCopyBytes(body.Graffiti), ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings), - AttesterSlashings: CopyAttesterSlashings(body.AttesterSlashings), - Attestations: CopyAttestations(body.Attestations), + AttesterSlashings: copySlice(body.AttesterSlashings), + Attestations: copySlice(body.Attestations), Deposits: CopyDeposits(body.Deposits), VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits), } @@ -170,8 +106,8 @@ func CopyBeaconBlockBodyAltair(body *BeaconBlockBodyAltair) *BeaconBlockBodyAlta Eth1Data: CopyETH1Data(body.Eth1Data), Graffiti: bytesutil.SafeCopyBytes(body.Graffiti), ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings), - AttesterSlashings: CopyAttesterSlashings(body.AttesterSlashings), - Attestations: CopyAttestations(body.Attestations), + AttesterSlashings: copySlice(body.AttesterSlashings), + Attestations: copySlice(body.Attestations), Deposits: CopyDeposits(body.Deposits), VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits), SyncAggregate: CopySyncAggregate(body.SyncAggregate), @@ -229,92 +165,6 @@ func CopyBeaconBlockHeader(header *BeaconBlockHeader) *BeaconBlockHeader { } } -// CopyAttesterSlashings copies the provided AttesterSlashings array. -func CopyAttesterSlashings(slashings []*AttesterSlashing) []*AttesterSlashing { - if slashings == nil { - return nil - } - newSlashings := make([]*AttesterSlashing, len(slashings)) - for i, slashing := range slashings { - newSlashings[i] = &AttesterSlashing{ - Attestation_1: CopyIndexedAttestation(slashing.Attestation_1), - Attestation_2: CopyIndexedAttestation(slashing.Attestation_2), - } - } - return newSlashings -} - -// CopyAttesterSlashingsElectra copies the provided AttesterSlashings array. -func CopyAttesterSlashingsElectra(slashings []*AttesterSlashingElectra) []*AttesterSlashingElectra { - if slashings == nil { - return nil - } - newSlashings := make([]*AttesterSlashingElectra, len(slashings)) - for i, slashing := range slashings { - newSlashings[i] = &AttesterSlashingElectra{ - Attestation_1: CopyIndexedAttestationElectra(slashing.Attestation_1), - Attestation_2: CopyIndexedAttestationElectra(slashing.Attestation_2), - } - } - return newSlashings -} - -// CopyIndexedAttestation copies the provided IndexedAttestation. -func CopyIndexedAttestation(indexedAtt *IndexedAttestation) *IndexedAttestation { - var indices []uint64 - if indexedAtt == nil { - return nil - } else if indexedAtt.AttestingIndices != nil { - indices = make([]uint64, len(indexedAtt.AttestingIndices)) - copy(indices, indexedAtt.AttestingIndices) - } - return &IndexedAttestation{ - AttestingIndices: indices, - Data: CopyAttestationData(indexedAtt.Data), - Signature: bytesutil.SafeCopyBytes(indexedAtt.Signature), - } -} - -// CopyIndexedAttestationElectra copies the provided IndexedAttestation. -func CopyIndexedAttestationElectra(indexedAtt *IndexedAttestationElectra) *IndexedAttestationElectra { - var indices []uint64 - if indexedAtt == nil { - return nil - } else if indexedAtt.AttestingIndices != nil { - indices = make([]uint64, len(indexedAtt.AttestingIndices)) - copy(indices, indexedAtt.AttestingIndices) - } - return &IndexedAttestationElectra{ - AttestingIndices: indices, - Data: CopyAttestationData(indexedAtt.Data), - Signature: bytesutil.SafeCopyBytes(indexedAtt.Signature), - } -} - -// CopyAttestations copies the provided Attestation array. -func CopyAttestations(attestations []*Attestation) []*Attestation { - if attestations == nil { - return nil - } - newAttestations := make([]*Attestation, len(attestations)) - for i, att := range attestations { - newAttestations[i] = CopyAttestation(att) - } - return newAttestations -} - -// CopyAttestations copies the provided AttestationElectra array. -func CopyAttestationsElectra(attestations []*AttestationElectra) []*AttestationElectra { - if attestations == nil { - return nil - } - newAttestations := make([]*AttestationElectra, len(attestations)) - for i, att := range attestations { - newAttestations[i] = CopyAttestationElectra(att) - } - return newAttestations -} - // CopyDeposits copies the provided deposit array. func CopyDeposits(deposits []*Deposit) []*Deposit { if deposits == nil { @@ -468,8 +318,8 @@ func CopyBeaconBlockBodyBellatrix(body *BeaconBlockBodyBellatrix) *BeaconBlockBo Eth1Data: CopyETH1Data(body.Eth1Data), Graffiti: bytesutil.SafeCopyBytes(body.Graffiti), ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings), - AttesterSlashings: CopyAttesterSlashings(body.AttesterSlashings), - Attestations: CopyAttestations(body.Attestations), + AttesterSlashings: copySlice(body.AttesterSlashings), + Attestations: copySlice(body.Attestations), Deposits: CopyDeposits(body.Deposits), VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits), SyncAggregate: CopySyncAggregate(body.SyncAggregate), @@ -512,8 +362,8 @@ func CopyBeaconBlockBodyCapella(body *BeaconBlockBodyCapella) *BeaconBlockBodyCa Eth1Data: CopyETH1Data(body.Eth1Data), Graffiti: bytesutil.SafeCopyBytes(body.Graffiti), ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings), - AttesterSlashings: CopyAttesterSlashings(body.AttesterSlashings), - Attestations: CopyAttestations(body.Attestations), + AttesterSlashings: copySlice(body.AttesterSlashings), + Attestations: copySlice(body.Attestations), Deposits: CopyDeposits(body.Deposits), VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits), SyncAggregate: CopySyncAggregate(body.SyncAggregate), @@ -557,8 +407,8 @@ func CopyBlindedBeaconBlockBodyCapella(body *BlindedBeaconBlockBodyCapella) *Bli Eth1Data: CopyETH1Data(body.Eth1Data), Graffiti: bytesutil.SafeCopyBytes(body.Graffiti), ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings), - AttesterSlashings: CopyAttesterSlashings(body.AttesterSlashings), - Attestations: CopyAttestations(body.Attestations), + AttesterSlashings: copySlice(body.AttesterSlashings), + Attestations: copySlice(body.Attestations), Deposits: CopyDeposits(body.Deposits), VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits), SyncAggregate: CopySyncAggregate(body.SyncAggregate), @@ -602,8 +452,8 @@ func CopyBlindedBeaconBlockBodyDeneb(body *BlindedBeaconBlockBodyDeneb) *Blinded Eth1Data: CopyETH1Data(body.Eth1Data), Graffiti: bytesutil.SafeCopyBytes(body.Graffiti), ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings), - AttesterSlashings: CopyAttesterSlashings(body.AttesterSlashings), - Attestations: CopyAttestations(body.Attestations), + AttesterSlashings: copySlice(body.AttesterSlashings), + Attestations: copySlice(body.Attestations), Deposits: CopyDeposits(body.Deposits), VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits), SyncAggregate: CopySyncAggregate(body.SyncAggregate), @@ -648,8 +498,8 @@ func CopyBlindedBeaconBlockBodyElectra(body *BlindedBeaconBlockBodyElectra) *Bli Eth1Data: CopyETH1Data(body.Eth1Data), Graffiti: bytesutil.SafeCopyBytes(body.Graffiti), ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings), - AttesterSlashings: CopyAttesterSlashingsElectra(body.AttesterSlashings), - Attestations: CopyAttestationsElectra(body.Attestations), + AttesterSlashings: copySlice(body.AttesterSlashings), + Attestations: copySlice(body.Attestations), Deposits: CopyDeposits(body.Deposits), VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits), SyncAggregate: CopySyncAggregate(body.SyncAggregate), @@ -694,8 +544,8 @@ func CopyBlindedBeaconBlockBodyBellatrix(body *BlindedBeaconBlockBodyBellatrix) Eth1Data: CopyETH1Data(body.Eth1Data), Graffiti: bytesutil.SafeCopyBytes(body.Graffiti), ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings), - AttesterSlashings: CopyAttesterSlashings(body.AttesterSlashings), - Attestations: CopyAttestations(body.Attestations), + AttesterSlashings: copySlice(body.AttesterSlashings), + Attestations: copySlice(body.Attestations), Deposits: CopyDeposits(body.Deposits), VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits), SyncAggregate: CopySyncAggregate(body.SyncAggregate), @@ -763,8 +613,8 @@ func CopyBeaconBlockBodyDeneb(body *BeaconBlockBodyDeneb) *BeaconBlockBodyDeneb Eth1Data: CopyETH1Data(body.Eth1Data), Graffiti: bytesutil.SafeCopyBytes(body.Graffiti), ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings), - AttesterSlashings: CopyAttesterSlashings(body.AttesterSlashings), - Attestations: CopyAttestations(body.Attestations), + AttesterSlashings: copySlice(body.AttesterSlashings), + Attestations: copySlice(body.Attestations), Deposits: CopyDeposits(body.Deposits), VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits), SyncAggregate: CopySyncAggregate(body.SyncAggregate), @@ -809,8 +659,8 @@ func CopyBeaconBlockBodyElectra(body *BeaconBlockBodyElectra) *BeaconBlockBodyEl Eth1Data: CopyETH1Data(body.Eth1Data), Graffiti: bytesutil.SafeCopyBytes(body.Graffiti), ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings), - AttesterSlashings: CopyAttesterSlashingsElectra(body.AttesterSlashings), - Attestations: CopyAttestationsElectra(body.Attestations), + AttesterSlashings: copySlice(body.AttesterSlashings), + Attestations: copySlice(body.Attestations), Deposits: CopyDeposits(body.Deposits), VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits), SyncAggregate: CopySyncAggregate(body.SyncAggregate), diff --git a/proto/prysm/v1alpha1/cloners_test.go b/proto/prysm/v1alpha1/cloners_test.go index 90dbdd450381..78baa17935d5 100644 --- a/proto/prysm/v1alpha1/cloners_test.go +++ b/proto/prysm/v1alpha1/cloners_test.go @@ -20,45 +20,6 @@ func TestCopyETH1Data(t *testing.T) { assert.NotEmpty(t, got, "Copied eth1data has empty fields") } -func TestCopyPendingAttestation(t *testing.T) { - pa := genPendingAttestation() - - got := v1alpha1.CopyPendingAttestation(pa) - if !reflect.DeepEqual(got, pa) { - t.Errorf("CopyPendingAttestation() = %v, want %v", got, pa) - } - assert.NotEmpty(t, got, "Copied pending attestation has empty fields") -} - -func TestCopyAttestation(t *testing.T) { - att := genAttestation() - - got := v1alpha1.CopyAttestation(att) - if !reflect.DeepEqual(got, att) { - t.Errorf("CopyAttestation() = %v, want %v", got, att) - } - assert.NotEmpty(t, got, "Copied attestation has empty fields") -} -func TestCopyAttestationData(t *testing.T) { - att := genAttData() - - got := v1alpha1.CopyAttestationData(att) - if !reflect.DeepEqual(got, att) { - t.Errorf("CopyAttestationData() = %v, want %v", got, att) - } - assert.NotEmpty(t, got, "Copied attestation data has empty fields") -} - -func TestCopyCheckpoint(t *testing.T) { - cp := genCheckpoint() - - got := v1alpha1.CopyCheckpoint(cp) - if !reflect.DeepEqual(got, cp) { - t.Errorf("CopyCheckpoint() = %v, want %v", got, cp) - } - assert.NotEmpty(t, got, "Copied checkpoint has empty fields") -} - func TestCopySignedBeaconBlock(t *testing.T) { blk := genSignedBeaconBlock() @@ -159,36 +120,6 @@ func TestCopyBeaconBlockHeader(t *testing.T) { assert.NotEmpty(t, got, "Copied beacon block header has empty fields") } -func TestCopyAttesterSlashings(t *testing.T) { - as := genAttesterSlashings(10) - - got := v1alpha1.CopyAttesterSlashings(as) - if !reflect.DeepEqual(got, as) { - t.Errorf("CopyAttesterSlashings() = %v, want %v", got, as) - } - assert.NotEmpty(t, got, "Copied attester slashings have empty fields") -} - -func TestCopyIndexedAttestation(t *testing.T) { - ia := genIndexedAttestation() - - got := v1alpha1.CopyIndexedAttestation(ia) - if !reflect.DeepEqual(got, ia) { - t.Errorf("CopyIndexedAttestation() = %v, want %v", got, ia) - } - assert.NotEmpty(t, got, "Copied indexed attestation has empty fields") -} - -func TestCopyAttestations(t *testing.T) { - atts := genAttestations(10) - - got := v1alpha1.CopyAttestations(atts) - if !reflect.DeepEqual(got, atts) { - t.Errorf("CopyAttestations() = %v, want %v", got, atts) - } - assert.NotEmpty(t, got, "Copied attestations have empty fields") -} - func TestCopyDeposits(t *testing.T) { d := genDeposits(10) @@ -302,7 +233,7 @@ func TestCopyPendingAttestationSlice(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := v1alpha1.CopyPendingAttestationSlice(tt.input); !reflect.DeepEqual(got, tt.input) { + if got := tt.input; !reflect.DeepEqual(got, tt.input) { t.Errorf("CopyPendingAttestationSlice() = %v, want %v", got, tt.input) } }) @@ -518,42 +449,6 @@ func TestCopyHistoricalSummaries(t *testing.T) { } } -func TestCopyAttestationElectra(t *testing.T) { - att := genAttestationElectra() - - got := v1alpha1.CopyAttestationElectra(att) - if !reflect.DeepEqual(got, att) { - t.Errorf("TestCopyAttestationElectra() = %v, want %v", got, att) - } -} - -func TestCopyAttesterSlashingsElectra(t *testing.T) { - as := genAttesterSlashingsElectra(10) - - got := v1alpha1.CopyAttesterSlashingsElectra(as) - if !reflect.DeepEqual(got, as) { - t.Errorf("TestCopyAttesterSlashingsElectra() = %v, want %v", got, as) - } -} - -func TestCopyIndexedAttestationElectra(t *testing.T) { - ia := genIndexedAttestationElectra() - - got := v1alpha1.CopyIndexedAttestationElectra(ia) - if !reflect.DeepEqual(got, ia) { - t.Errorf("TestCopyIndexedAttestationElectra() = %v, want %v", got, ia) - } -} - -func TestCopyAttestationsElectra(t *testing.T) { - atts := genAttestationsElectra(10) - - got := v1alpha1.CopyAttestationsElectra(atts) - if !reflect.DeepEqual(got, atts) { - t.Errorf("TestCopyAttestationsElectra() = %v, want %v", got, atts) - } -} - func TestCopySignedBlindedBeaconBlockElectra(t *testing.T) { sbb := genSignedBlindedBeaconBlockElectra() diff --git a/proto/prysm/v1alpha1/export_test.go b/proto/prysm/v1alpha1/export_test.go new file mode 100644 index 000000000000..4d944620a8d4 --- /dev/null +++ b/proto/prysm/v1alpha1/export_test.go @@ -0,0 +1,3 @@ +package eth + +type Copier[T any] copier[T]