moving cloners to beacon_block.go and adding fuzzing (#14255)

* moving beacon block fields from cloners to individual files and adding fuzzing tests

* adding missed tests

* fixing tests:

* removing deep not equals for now

* adding clarifying comment
This commit is contained in:
james-prysm
2024-07-23 11:42:35 -05:00
committed by GitHub
parent 4d823acf45
commit b108d5bf54
20 changed files with 336 additions and 484 deletions

View File

@@ -58,10 +58,9 @@ func AreEth1DataEqual(a, b *ethpb.Eth1Data) bool {
// votes to see if they match the eth1data.
func Eth1DataHasEnoughSupport(beaconState state.ReadOnlyBeaconState, data *ethpb.Eth1Data) (bool, error) {
voteCount := uint64(0)
data = ethpb.CopyETH1Data(data)
for _, vote := range beaconState.Eth1DataVotes() {
if AreEth1DataEqual(vote, data) {
if AreEth1DataEqual(vote, data.Copy()) {
voteCount++
}
}

View File

@@ -186,7 +186,7 @@ func TestProcessEth1Data_SetsCorrectly(t *testing.T) {
if len(newETH1DataVotes) <= 1 {
t.Error("Expected new ETH1 data votes to have length > 1")
}
if !proto.Equal(beaconState.Eth1Data(), ethpb.CopyETH1Data(b.Block.Body.Eth1Data)) {
if !proto.Equal(beaconState.Eth1Data(), b.Block.Body.Eth1Data.Copy()) {
t.Errorf(
"Expected latest eth1 data to have been set to %v, received %v",
b.Block.Body.Eth1Data,

View File

@@ -70,7 +70,7 @@ func TestExecuteAltairStateTransitionNoVerify_FullProcess(t *testing.T) {
}
indices, err := altair.NextSyncCommitteeIndices(context.Background(), beaconState)
require.NoError(t, err)
h := ethpb.CopyBeaconBlockHeader(beaconState.LatestBlockHeader())
h := beaconState.LatestBlockHeader().Copy()
prevStateRoot, err := beaconState.HashTreeRoot(context.Background())
require.NoError(t, err)
h.StateRoot = prevStateRoot[:]
@@ -157,7 +157,7 @@ func TestExecuteAltairStateTransitionNoVerifySignature_CouldNotVerifyStateRoot(t
}
indices, err := altair.NextSyncCommitteeIndices(context.Background(), beaconState)
require.NoError(t, err)
h := ethpb.CopyBeaconBlockHeader(beaconState.LatestBlockHeader())
h := beaconState.LatestBlockHeader().Copy()
prevStateRoot, err := beaconState.HashTreeRoot(context.Background())
require.NoError(t, err)
h.StateRoot = prevStateRoot[:]

View File

@@ -72,7 +72,7 @@ func TestExecuteBellatrixStateTransitionNoVerify_FullProcess(t *testing.T) {
}
indices, err := altair.NextSyncCommitteeIndices(context.Background(), beaconState)
require.NoError(t, err)
h := ethpb.CopyBeaconBlockHeader(beaconState.LatestBlockHeader())
h := beaconState.LatestBlockHeader().Copy()
prevStateRoot, err := beaconState.HashTreeRoot(context.Background())
require.NoError(t, err)
h.StateRoot = prevStateRoot[:]
@@ -159,7 +159,7 @@ func TestExecuteBellatrixStateTransitionNoVerifySignature_CouldNotVerifyStateRoo
}
indices, err := altair.NextSyncCommitteeIndices(context.Background(), beaconState)
require.NoError(t, err)
h := ethpb.CopyBeaconBlockHeader(beaconState.LatestBlockHeader())
h := beaconState.LatestBlockHeader().Copy()
prevStateRoot, err := beaconState.HashTreeRoot(context.Background())
require.NoError(t, err)
h.StateRoot = prevStateRoot[:]

View File

@@ -35,5 +35,5 @@ func (b *BeaconState) pendingBalanceDepositsVal() []*ethpb.PendingBalanceDeposit
return nil
}
return ethpb.CopyPendingBalanceDeposits(b.pendingBalanceDeposits)
return ethpb.CopySlice(b.pendingBalanceDeposits)
}

View File

@@ -59,5 +59,5 @@ func (b *BeaconState) pendingConsolidationsVal() []*ethpb.PendingConsolidation {
return nil
}
return ethpb.CopyPendingConsolidations(b.pendingConsolidations)
return ethpb.CopySlice(b.pendingConsolidations)
}

View File

@@ -23,7 +23,7 @@ func (b *BeaconState) eth1DataVal() *ethpb.Eth1Data {
return nil
}
return ethpb.CopyETH1Data(b.eth1Data)
return b.eth1Data.Copy()
}
// Eth1DataVotes corresponds to votes from Ethereum on the canonical proof-of-work chain
@@ -49,7 +49,7 @@ func (b *BeaconState) eth1DataVotesVal() []*ethpb.Eth1Data {
res := make([]*ethpb.Eth1Data, len(b.eth1DataVotes))
for i := 0; i < len(res); i++ {
res[i] = ethpb.CopyETH1Data(b.eth1DataVotes[i])
res[i] = b.eth1DataVotes[i].Copy()
}
return res
}

View File

@@ -103,5 +103,5 @@ func (b *BeaconState) HistoricalSummaries() ([]*ethpb.HistoricalSummary, error)
// historicalSummariesVal of the beacon state.
// This assumes that a lock is already held on BeaconState.
func (b *BeaconState) historicalSummariesVal() []*ethpb.HistoricalSummary {
return ethpb.CopyHistoricalSummaries(b.historicalSummaries)
return ethpb.CopySlice(b.historicalSummaries)
}

View File

@@ -184,7 +184,7 @@ func (b *BeaconState) ExpectedWithdrawals() ([]*enginev1.Withdrawal, uint64, err
}
func (b *BeaconState) pendingPartialWithdrawalsVal() []*ethpb.PendingPartialWithdrawal {
return ethpb.CopyPendingPartialWithdrawals(b.pendingPartialWithdrawals)
return ethpb.CopySlice(b.pendingPartialWithdrawals)
}
func (b *BeaconState) NumPendingPartialWithdrawals() (uint64, error) {

View File

@@ -15,7 +15,7 @@ func (b *BeaconState) SetLatestBlockHeader(val *ethpb.BeaconBlockHeader) error {
b.lock.Lock()
defer b.lock.Unlock()
b.latestBlockHeader = ethpb.CopyBeaconBlockHeader(val)
b.latestBlockHeader = val.Copy()
b.markFieldAsDirty(types.LatestBlockHeader)
return nil
}

View File

@@ -81,7 +81,7 @@ func WithdrawalCredentialsHash(withdrawalKey bls.SecretKey) []byte {
// VerifyDepositSignature verifies the correctness of Eth1 deposit BLS signature
func VerifyDepositSignature(dd *ethpb.Deposit_Data, domain []byte) error {
ddCopy := ethpb.CopyDepositData(dd)
ddCopy := dd.Copy()
publicKey, err := bls.PublicKeyFromBytes(ddCopy.PublicKey)
if err != nil {
return errors.Wrap(err, "could not convert bytes to public key")

View File

@@ -308,7 +308,9 @@ go_library(
name = "go_default_library",
srcs = [
"attestation.go",
"beacon_block.go",
"cloners.go",
"eip_7521.go",
"sync_committee_mainnet.go",
"sync_committee_minimal.go", # keep
":ssz_generated_non_core", # keep
@@ -372,8 +374,11 @@ go_test(
name = "go_default_test",
srcs = [
"attestation_fuzz_test.go",
"beacon_block_fuzz_test.go",
"cloners_test.go",
"eip_7521_fuzz_test.go",
"export_test.go",
"fuzz_test.go",
],
embed = [":go_default_library"],
deps = [

View File

@@ -1,15 +1,12 @@
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) {
func TestCopyAttestation_Fuzz(t *testing.T) {
fuzzCopies(t, &eth.Checkpoint{})
fuzzCopies(t, &eth.AttestationData{})
fuzzCopies(t, &eth.Attestation{})
@@ -20,19 +17,3 @@ func TestCopyExecutionPayloadHeader_Fuzz(t *testing.T) {
fuzzCopies(t, &eth.AttesterSlashing{})
fuzzCopies(t, &eth.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
}
})
}

View File

@@ -0,0 +1,156 @@
package eth
import "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
// Copy --
func (data *Eth1Data) Copy() *Eth1Data {
if data == nil {
return nil
}
return &Eth1Data{
DepositRoot: bytesutil.SafeCopyBytes(data.DepositRoot),
DepositCount: data.DepositCount,
BlockHash: bytesutil.SafeCopyBytes(data.BlockHash),
}
}
// Copy --
func (slashing *ProposerSlashing) Copy() *ProposerSlashing {
if slashing == nil {
return nil
}
return &ProposerSlashing{
Header_1: slashing.Header_1.Copy(),
Header_2: slashing.Header_2.Copy(),
}
}
// Copy --
func (header *SignedBeaconBlockHeader) Copy() *SignedBeaconBlockHeader {
if header == nil {
return nil
}
return &SignedBeaconBlockHeader{
Header: header.Header.Copy(),
Signature: bytesutil.SafeCopyBytes(header.Signature),
}
}
// Copy --
func (header *BeaconBlockHeader) Copy() *BeaconBlockHeader {
if header == nil {
return nil
}
parentRoot := bytesutil.SafeCopyBytes(header.ParentRoot)
stateRoot := bytesutil.SafeCopyBytes(header.StateRoot)
bodyRoot := bytesutil.SafeCopyBytes(header.BodyRoot)
return &BeaconBlockHeader{
Slot: header.Slot,
ProposerIndex: header.ProposerIndex,
ParentRoot: parentRoot,
StateRoot: stateRoot,
BodyRoot: bodyRoot,
}
}
// Copy --
func (deposit *Deposit) Copy() *Deposit {
if deposit == nil {
return nil
}
return &Deposit{
Proof: bytesutil.SafeCopy2dBytes(deposit.Proof),
Data: deposit.Data.Copy(),
}
}
// Copy --
func (depData *Deposit_Data) Copy() *Deposit_Data {
if depData == nil {
return nil
}
return &Deposit_Data{
PublicKey: bytesutil.SafeCopyBytes(depData.PublicKey),
WithdrawalCredentials: bytesutil.SafeCopyBytes(depData.WithdrawalCredentials),
Amount: depData.Amount,
Signature: bytesutil.SafeCopyBytes(depData.Signature),
}
}
// Copy --
func (exit *SignedVoluntaryExit) Copy() *SignedVoluntaryExit {
if exit == nil {
return nil
}
return &SignedVoluntaryExit{
Exit: exit.Exit.Copy(),
Signature: bytesutil.SafeCopyBytes(exit.Signature),
}
}
// Copy --
func (exit *VoluntaryExit) Copy() *VoluntaryExit {
if exit == nil {
return nil
}
return &VoluntaryExit{
Epoch: exit.Epoch,
ValidatorIndex: exit.ValidatorIndex,
}
}
// Copy --
func (a *SyncAggregate) Copy() *SyncAggregate {
if a == nil {
return nil
}
return &SyncAggregate{
SyncCommitteeBits: bytesutil.SafeCopyBytes(a.SyncCommitteeBits),
SyncCommitteeSignature: bytesutil.SafeCopyBytes(a.SyncCommitteeSignature),
}
}
// Copy --
func (change *SignedBLSToExecutionChange) Copy() *SignedBLSToExecutionChange {
if change == nil {
return nil
}
return &SignedBLSToExecutionChange{
Message: change.Message.Copy(),
Signature: bytesutil.SafeCopyBytes(change.Signature),
}
}
// Copy --
func (change *BLSToExecutionChange) Copy() *BLSToExecutionChange {
if change == nil {
return nil
}
return &BLSToExecutionChange{
ValidatorIndex: change.ValidatorIndex,
FromBlsPubkey: bytesutil.SafeCopyBytes(change.FromBlsPubkey),
ToExecutionAddress: bytesutil.SafeCopyBytes(change.ToExecutionAddress),
}
}
// Copy --
func (summary *HistoricalSummary) Copy() *HistoricalSummary {
if summary == nil {
return nil
}
return &HistoricalSummary{
BlockSummaryRoot: bytesutil.SafeCopyBytes(summary.BlockSummaryRoot),
StateSummaryRoot: bytesutil.SafeCopyBytes(summary.StateSummaryRoot),
}
}
// Copy --
func (pbd *PendingBalanceDeposit) Copy() *PendingBalanceDeposit {
if pbd == nil {
return nil
}
return &PendingBalanceDeposit{
Index: pbd.Index,
Amount: pbd.Amount,
}
}

View File

@@ -0,0 +1,23 @@
package eth_test
import (
"testing"
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
)
func TestCopyBeaconBlockFields_Fuzz(t *testing.T) {
fuzzCopies(t, &eth.Eth1Data{})
fuzzCopies(t, &eth.ProposerSlashing{})
fuzzCopies(t, &eth.SignedBeaconBlockHeader{})
fuzzCopies(t, &eth.BeaconBlockHeader{})
fuzzCopies(t, &eth.Deposit{})
fuzzCopies(t, &eth.Deposit_Data{})
fuzzCopies(t, &eth.SignedVoluntaryExit{})
fuzzCopies(t, &eth.VoluntaryExit{})
fuzzCopies(t, &eth.SyncAggregate{})
fuzzCopies(t, &eth.SignedBLSToExecutionChange{})
fuzzCopies(t, &eth.BLSToExecutionChange{})
fuzzCopies(t, &eth.HistoricalSummary{})
fuzzCopies(t, &eth.PendingBalanceDeposit{})
}

View File

@@ -8,7 +8,7 @@ type copier[T any] interface {
Copy() T
}
func copySlice[T any, C copier[T]](original []C) []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++ {
@@ -17,18 +17,6 @@ func copySlice[T any, C copier[T]](original []C) []T {
return newSlice
}
// CopyETH1Data copies the provided eth1data object.
func CopyETH1Data(data *Eth1Data) *Eth1Data {
if data == nil {
return nil
}
return &Eth1Data{
DepositRoot: bytesutil.SafeCopyBytes(data.DepositRoot),
DepositCount: data.DepositCount,
BlockHash: bytesutil.SafeCopyBytes(data.BlockHash),
}
}
// CopySignedBeaconBlock copies the provided SignedBeaconBlock.
func CopySignedBeaconBlock(sigBlock *SignedBeaconBlock) *SignedBeaconBlock {
if sigBlock == nil {
@@ -61,13 +49,13 @@ func CopyBeaconBlockBody(body *BeaconBlockBody) *BeaconBlockBody {
}
return &BeaconBlockBody{
RandaoReveal: bytesutil.SafeCopyBytes(body.RandaoReveal),
Eth1Data: CopyETH1Data(body.Eth1Data),
Eth1Data: body.Eth1Data.Copy(),
Graffiti: bytesutil.SafeCopyBytes(body.Graffiti),
ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings),
AttesterSlashings: copySlice(body.AttesterSlashings),
Attestations: copySlice(body.Attestations),
Deposits: CopyDeposits(body.Deposits),
VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits),
ProposerSlashings: CopySlice(body.ProposerSlashings),
AttesterSlashings: CopySlice(body.AttesterSlashings),
Attestations: CopySlice(body.Attestations),
Deposits: CopySlice(body.Deposits),
VoluntaryExits: CopySlice(body.VoluntaryExits),
}
}
@@ -103,127 +91,14 @@ func CopyBeaconBlockBodyAltair(body *BeaconBlockBodyAltair) *BeaconBlockBodyAlta
}
return &BeaconBlockBodyAltair{
RandaoReveal: bytesutil.SafeCopyBytes(body.RandaoReveal),
Eth1Data: CopyETH1Data(body.Eth1Data),
Eth1Data: body.Eth1Data.Copy(),
Graffiti: bytesutil.SafeCopyBytes(body.Graffiti),
ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings),
AttesterSlashings: copySlice(body.AttesterSlashings),
Attestations: copySlice(body.Attestations),
Deposits: CopyDeposits(body.Deposits),
VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits),
SyncAggregate: CopySyncAggregate(body.SyncAggregate),
}
}
// CopyProposerSlashings copies the provided ProposerSlashing array.
func CopyProposerSlashings(slashings []*ProposerSlashing) []*ProposerSlashing {
if slashings == nil {
return nil
}
newSlashings := make([]*ProposerSlashing, len(slashings))
for i, att := range slashings {
newSlashings[i] = CopyProposerSlashing(att)
}
return newSlashings
}
// CopyProposerSlashing copies the provided ProposerSlashing.
func CopyProposerSlashing(slashing *ProposerSlashing) *ProposerSlashing {
if slashing == nil {
return nil
}
return &ProposerSlashing{
Header_1: CopySignedBeaconBlockHeader(slashing.Header_1),
Header_2: CopySignedBeaconBlockHeader(slashing.Header_2),
}
}
// CopySignedBeaconBlockHeader copies the provided SignedBeaconBlockHeader.
func CopySignedBeaconBlockHeader(header *SignedBeaconBlockHeader) *SignedBeaconBlockHeader {
if header == nil {
return nil
}
return &SignedBeaconBlockHeader{
Header: CopyBeaconBlockHeader(header.Header),
Signature: bytesutil.SafeCopyBytes(header.Signature),
}
}
// CopyBeaconBlockHeader copies the provided BeaconBlockHeader.
func CopyBeaconBlockHeader(header *BeaconBlockHeader) *BeaconBlockHeader {
if header == nil {
return nil
}
parentRoot := bytesutil.SafeCopyBytes(header.ParentRoot)
stateRoot := bytesutil.SafeCopyBytes(header.StateRoot)
bodyRoot := bytesutil.SafeCopyBytes(header.BodyRoot)
return &BeaconBlockHeader{
Slot: header.Slot,
ProposerIndex: header.ProposerIndex,
ParentRoot: parentRoot,
StateRoot: stateRoot,
BodyRoot: bodyRoot,
}
}
// CopyDeposits copies the provided deposit array.
func CopyDeposits(deposits []*Deposit) []*Deposit {
if deposits == nil {
return nil
}
newDeposits := make([]*Deposit, len(deposits))
for i, dep := range deposits {
newDeposits[i] = CopyDeposit(dep)
}
return newDeposits
}
// CopyDeposit copies the provided deposit.
func CopyDeposit(deposit *Deposit) *Deposit {
if deposit == nil {
return nil
}
return &Deposit{
Proof: bytesutil.SafeCopy2dBytes(deposit.Proof),
Data: CopyDepositData(deposit.Data),
}
}
// CopyDepositData copies the provided deposit data.
func CopyDepositData(depData *Deposit_Data) *Deposit_Data {
if depData == nil {
return nil
}
return &Deposit_Data{
PublicKey: bytesutil.SafeCopyBytes(depData.PublicKey),
WithdrawalCredentials: bytesutil.SafeCopyBytes(depData.WithdrawalCredentials),
Amount: depData.Amount,
Signature: bytesutil.SafeCopyBytes(depData.Signature),
}
}
// CopySignedVoluntaryExits copies the provided SignedVoluntaryExits array.
func CopySignedVoluntaryExits(exits []*SignedVoluntaryExit) []*SignedVoluntaryExit {
if exits == nil {
return nil
}
newExits := make([]*SignedVoluntaryExit, len(exits))
for i, exit := range exits {
newExits[i] = CopySignedVoluntaryExit(exit)
}
return newExits
}
// CopySignedVoluntaryExit copies the provided SignedVoluntaryExit.
func CopySignedVoluntaryExit(exit *SignedVoluntaryExit) *SignedVoluntaryExit {
if exit == nil {
return nil
}
return &SignedVoluntaryExit{
Exit: &VoluntaryExit{
Epoch: exit.Exit.Epoch,
ValidatorIndex: exit.Exit.ValidatorIndex,
},
Signature: bytesutil.SafeCopyBytes(exit.Signature),
ProposerSlashings: CopySlice(body.ProposerSlashings),
AttesterSlashings: CopySlice(body.AttesterSlashings),
Attestations: CopySlice(body.Attestations),
Deposits: CopySlice(body.Deposits),
VoluntaryExits: CopySlice(body.VoluntaryExits),
SyncAggregate: body.SyncAggregate.Copy(),
}
}
@@ -272,17 +147,6 @@ func CopySyncCommitteeContribution(c *SyncCommitteeContribution) *SyncCommitteeC
}
}
// CopySyncAggregate copies the provided sync aggregate object.
func CopySyncAggregate(a *SyncAggregate) *SyncAggregate {
if a == nil {
return nil
}
return &SyncAggregate{
SyncCommitteeBits: bytesutil.SafeCopyBytes(a.SyncCommitteeBits),
SyncCommitteeSignature: bytesutil.SafeCopyBytes(a.SyncCommitteeSignature),
}
}
// CopySignedBeaconBlockBellatrix copies the provided SignedBeaconBlockBellatrix.
func CopySignedBeaconBlockBellatrix(sigBlock *SignedBeaconBlockBellatrix) *SignedBeaconBlockBellatrix {
if sigBlock == nil {
@@ -315,14 +179,14 @@ func CopyBeaconBlockBodyBellatrix(body *BeaconBlockBodyBellatrix) *BeaconBlockBo
}
return &BeaconBlockBodyBellatrix{
RandaoReveal: bytesutil.SafeCopyBytes(body.RandaoReveal),
Eth1Data: CopyETH1Data(body.Eth1Data),
Eth1Data: body.Eth1Data.Copy(),
Graffiti: bytesutil.SafeCopyBytes(body.Graffiti),
ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings),
AttesterSlashings: copySlice(body.AttesterSlashings),
Attestations: copySlice(body.Attestations),
Deposits: CopyDeposits(body.Deposits),
VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits),
SyncAggregate: CopySyncAggregate(body.SyncAggregate),
ProposerSlashings: CopySlice(body.ProposerSlashings),
AttesterSlashings: CopySlice(body.AttesterSlashings),
Attestations: CopySlice(body.Attestations),
Deposits: CopySlice(body.Deposits),
VoluntaryExits: CopySlice(body.VoluntaryExits),
SyncAggregate: body.SyncAggregate.Copy(),
ExecutionPayload: body.ExecutionPayload.Copy(),
}
}
@@ -359,16 +223,16 @@ func CopyBeaconBlockBodyCapella(body *BeaconBlockBodyCapella) *BeaconBlockBodyCa
}
return &BeaconBlockBodyCapella{
RandaoReveal: bytesutil.SafeCopyBytes(body.RandaoReveal),
Eth1Data: CopyETH1Data(body.Eth1Data),
Eth1Data: body.Eth1Data.Copy(),
Graffiti: bytesutil.SafeCopyBytes(body.Graffiti),
ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings),
AttesterSlashings: copySlice(body.AttesterSlashings),
Attestations: copySlice(body.Attestations),
Deposits: CopyDeposits(body.Deposits),
VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits),
SyncAggregate: CopySyncAggregate(body.SyncAggregate),
ProposerSlashings: CopySlice(body.ProposerSlashings),
AttesterSlashings: CopySlice(body.AttesterSlashings),
Attestations: CopySlice(body.Attestations),
Deposits: CopySlice(body.Deposits),
VoluntaryExits: CopySlice(body.VoluntaryExits),
SyncAggregate: body.SyncAggregate.Copy(),
ExecutionPayload: body.ExecutionPayload.Copy(),
BlsToExecutionChanges: CopyBLSToExecutionChanges(body.BlsToExecutionChanges),
BlsToExecutionChanges: CopySlice(body.BlsToExecutionChanges),
}
}
@@ -404,16 +268,16 @@ func CopyBlindedBeaconBlockBodyCapella(body *BlindedBeaconBlockBodyCapella) *Bli
}
return &BlindedBeaconBlockBodyCapella{
RandaoReveal: bytesutil.SafeCopyBytes(body.RandaoReveal),
Eth1Data: CopyETH1Data(body.Eth1Data),
Eth1Data: body.Eth1Data.Copy(),
Graffiti: bytesutil.SafeCopyBytes(body.Graffiti),
ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings),
AttesterSlashings: copySlice(body.AttesterSlashings),
Attestations: copySlice(body.Attestations),
Deposits: CopyDeposits(body.Deposits),
VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits),
SyncAggregate: CopySyncAggregate(body.SyncAggregate),
ProposerSlashings: CopySlice(body.ProposerSlashings),
AttesterSlashings: CopySlice(body.AttesterSlashings),
Attestations: CopySlice(body.Attestations),
Deposits: CopySlice(body.Deposits),
VoluntaryExits: CopySlice(body.VoluntaryExits),
SyncAggregate: body.SyncAggregate.Copy(),
ExecutionPayloadHeader: body.ExecutionPayloadHeader.Copy(),
BlsToExecutionChanges: CopyBLSToExecutionChanges(body.BlsToExecutionChanges),
BlsToExecutionChanges: CopySlice(body.BlsToExecutionChanges),
}
}
@@ -449,16 +313,16 @@ func CopyBlindedBeaconBlockBodyDeneb(body *BlindedBeaconBlockBodyDeneb) *Blinded
}
return &BlindedBeaconBlockBodyDeneb{
RandaoReveal: bytesutil.SafeCopyBytes(body.RandaoReveal),
Eth1Data: CopyETH1Data(body.Eth1Data),
Eth1Data: body.Eth1Data.Copy(),
Graffiti: bytesutil.SafeCopyBytes(body.Graffiti),
ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings),
AttesterSlashings: copySlice(body.AttesterSlashings),
Attestations: copySlice(body.Attestations),
Deposits: CopyDeposits(body.Deposits),
VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits),
SyncAggregate: CopySyncAggregate(body.SyncAggregate),
ProposerSlashings: CopySlice(body.ProposerSlashings),
AttesterSlashings: CopySlice(body.AttesterSlashings),
Attestations: CopySlice(body.Attestations),
Deposits: CopySlice(body.Deposits),
VoluntaryExits: CopySlice(body.VoluntaryExits),
SyncAggregate: body.SyncAggregate.Copy(),
ExecutionPayloadHeader: body.ExecutionPayloadHeader.Copy(),
BlsToExecutionChanges: CopyBLSToExecutionChanges(body.BlsToExecutionChanges),
BlsToExecutionChanges: CopySlice(body.BlsToExecutionChanges),
BlobKzgCommitments: CopyBlobKZGs(body.BlobKzgCommitments),
}
}
@@ -495,16 +359,16 @@ func CopyBlindedBeaconBlockBodyElectra(body *BlindedBeaconBlockBodyElectra) *Bli
}
return &BlindedBeaconBlockBodyElectra{
RandaoReveal: bytesutil.SafeCopyBytes(body.RandaoReveal),
Eth1Data: CopyETH1Data(body.Eth1Data),
Eth1Data: body.Eth1Data.Copy(),
Graffiti: bytesutil.SafeCopyBytes(body.Graffiti),
ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings),
AttesterSlashings: copySlice(body.AttesterSlashings),
Attestations: copySlice(body.Attestations),
Deposits: CopyDeposits(body.Deposits),
VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits),
SyncAggregate: CopySyncAggregate(body.SyncAggregate),
ProposerSlashings: CopySlice(body.ProposerSlashings),
AttesterSlashings: CopySlice(body.AttesterSlashings),
Attestations: CopySlice(body.Attestations),
Deposits: CopySlice(body.Deposits),
VoluntaryExits: CopySlice(body.VoluntaryExits),
SyncAggregate: body.SyncAggregate.Copy(),
ExecutionPayloadHeader: body.ExecutionPayloadHeader.Copy(),
BlsToExecutionChanges: CopyBLSToExecutionChanges(body.BlsToExecutionChanges),
BlsToExecutionChanges: CopySlice(body.BlsToExecutionChanges),
BlobKzgCommitments: CopyBlobKZGs(body.BlobKzgCommitments),
}
}
@@ -541,38 +405,18 @@ func CopyBlindedBeaconBlockBodyBellatrix(body *BlindedBeaconBlockBodyBellatrix)
}
return &BlindedBeaconBlockBodyBellatrix{
RandaoReveal: bytesutil.SafeCopyBytes(body.RandaoReveal),
Eth1Data: CopyETH1Data(body.Eth1Data),
Eth1Data: body.Eth1Data.Copy(),
Graffiti: bytesutil.SafeCopyBytes(body.Graffiti),
ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings),
AttesterSlashings: copySlice(body.AttesterSlashings),
Attestations: copySlice(body.Attestations),
Deposits: CopyDeposits(body.Deposits),
VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits),
SyncAggregate: CopySyncAggregate(body.SyncAggregate),
ProposerSlashings: CopySlice(body.ProposerSlashings),
AttesterSlashings: CopySlice(body.AttesterSlashings),
Attestations: CopySlice(body.Attestations),
Deposits: CopySlice(body.Deposits),
VoluntaryExits: CopySlice(body.VoluntaryExits),
SyncAggregate: body.SyncAggregate.Copy(),
ExecutionPayloadHeader: body.ExecutionPayloadHeader.Copy(),
}
}
func CopyBLSToExecutionChanges(changes []*SignedBLSToExecutionChange) []*SignedBLSToExecutionChange {
if changes == nil {
return nil
}
res := make([]*SignedBLSToExecutionChange, len(changes))
for i := 0; i < len(changes); i++ {
res[i] = &SignedBLSToExecutionChange{
Message: &BLSToExecutionChange{
ValidatorIndex: changes[i].Message.ValidatorIndex,
FromBlsPubkey: bytesutil.SafeCopyBytes(changes[i].Message.FromBlsPubkey),
ToExecutionAddress: bytesutil.SafeCopyBytes(changes[i].Message.ToExecutionAddress),
},
Signature: bytesutil.SafeCopyBytes(changes[i].Signature),
}
}
return res
}
// CopyBlobKZGs copies the provided blob kzgs object.
func CopyBlobKZGs(b [][]byte) [][]byte {
return bytesutil.SafeCopy2dBytes(b)
@@ -610,16 +454,16 @@ func CopyBeaconBlockBodyDeneb(body *BeaconBlockBodyDeneb) *BeaconBlockBodyDeneb
}
return &BeaconBlockBodyDeneb{
RandaoReveal: bytesutil.SafeCopyBytes(body.RandaoReveal),
Eth1Data: CopyETH1Data(body.Eth1Data),
Eth1Data: body.Eth1Data.Copy(),
Graffiti: bytesutil.SafeCopyBytes(body.Graffiti),
ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings),
AttesterSlashings: copySlice(body.AttesterSlashings),
Attestations: copySlice(body.Attestations),
Deposits: CopyDeposits(body.Deposits),
VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits),
SyncAggregate: CopySyncAggregate(body.SyncAggregate),
ProposerSlashings: CopySlice(body.ProposerSlashings),
AttesterSlashings: CopySlice(body.AttesterSlashings),
Attestations: CopySlice(body.Attestations),
Deposits: CopySlice(body.Deposits),
VoluntaryExits: CopySlice(body.VoluntaryExits),
SyncAggregate: body.SyncAggregate.Copy(),
ExecutionPayload: body.ExecutionPayload.Copy(),
BlsToExecutionChanges: CopyBLSToExecutionChanges(body.BlsToExecutionChanges),
BlsToExecutionChanges: CopySlice(body.BlsToExecutionChanges),
BlobKzgCommitments: CopyBlobKZGs(body.BlobKzgCommitments),
}
}
@@ -656,75 +500,16 @@ func CopyBeaconBlockBodyElectra(body *BeaconBlockBodyElectra) *BeaconBlockBodyEl
}
return &BeaconBlockBodyElectra{
RandaoReveal: bytesutil.SafeCopyBytes(body.RandaoReveal),
Eth1Data: CopyETH1Data(body.Eth1Data),
Eth1Data: body.Eth1Data.Copy(),
Graffiti: bytesutil.SafeCopyBytes(body.Graffiti),
ProposerSlashings: CopyProposerSlashings(body.ProposerSlashings),
AttesterSlashings: copySlice(body.AttesterSlashings),
Attestations: copySlice(body.Attestations),
Deposits: CopyDeposits(body.Deposits),
VoluntaryExits: CopySignedVoluntaryExits(body.VoluntaryExits),
SyncAggregate: CopySyncAggregate(body.SyncAggregate),
ProposerSlashings: CopySlice(body.ProposerSlashings),
AttesterSlashings: CopySlice(body.AttesterSlashings),
Attestations: CopySlice(body.Attestations),
Deposits: CopySlice(body.Deposits),
VoluntaryExits: CopySlice(body.VoluntaryExits),
SyncAggregate: body.SyncAggregate.Copy(),
ExecutionPayload: body.ExecutionPayload.Copy(),
BlsToExecutionChanges: CopyBLSToExecutionChanges(body.BlsToExecutionChanges),
BlsToExecutionChanges: CopySlice(body.BlsToExecutionChanges),
BlobKzgCommitments: CopyBlobKZGs(body.BlobKzgCommitments),
}
}
// CopyHistoricalSummaries copies the historical summaries.
func CopyHistoricalSummaries(summaries []*HistoricalSummary) []*HistoricalSummary {
if summaries == nil {
return nil
}
newSummaries := make([]*HistoricalSummary, len(summaries))
for i, s := range summaries {
newSummaries[i] = &HistoricalSummary{
BlockSummaryRoot: bytesutil.SafeCopyBytes(s.BlockSummaryRoot),
StateSummaryRoot: bytesutil.SafeCopyBytes(s.StateSummaryRoot),
}
}
return newSummaries
}
// CopyPartialWithdrawals copies the provided partial withdrawals.
func CopyPendingPartialWithdrawals(pws []*PendingPartialWithdrawal) []*PendingPartialWithdrawal {
if pws == nil {
return nil
}
newPws := make([]*PendingPartialWithdrawal, len(pws))
for i, pw := range pws {
newPws[i] = &PendingPartialWithdrawal{
Index: pw.Index,
Amount: pw.Amount,
WithdrawableEpoch: pw.WithdrawableEpoch,
}
}
return newPws
}
func CopyPendingConsolidations(pcs []*PendingConsolidation) []*PendingConsolidation {
if pcs == nil {
return nil
}
newPcs := make([]*PendingConsolidation, len(pcs))
for i, pc := range pcs {
newPcs[i] = &PendingConsolidation{
SourceIndex: pc.SourceIndex,
TargetIndex: pc.TargetIndex,
}
}
return newPcs
}
func CopyPendingBalanceDeposits(pbd []*PendingBalanceDeposit) []*PendingBalanceDeposit {
if pbd == nil {
return nil
}
newPbd := make([]*PendingBalanceDeposit, len(pbd))
for i, pb := range pbd {
newPbd[i] = &PendingBalanceDeposit{
Index: pb.Index,
Amount: pb.Amount,
}
}
return newPbd
}

View File

@@ -10,16 +10,6 @@ import (
"github.com/prysmaticlabs/prysm/v5/testing/assert"
)
func TestCopyETH1Data(t *testing.T) {
data := genEth1Data()
got := v1alpha1.CopyETH1Data(data)
if !reflect.DeepEqual(got, data) {
t.Errorf("CopyETH1Data() = %v, want %v", got, data)
}
assert.NotEmpty(t, got, "Copied eth1data has empty fields")
}
func TestCopySignedBeaconBlock(t *testing.T) {
blk := genSignedBeaconBlock()
@@ -80,96 +70,6 @@ func TestCopyBeaconBlockBodyAltair(t *testing.T) {
assert.NotEmpty(t, bb, "Copied beacon block body altair has empty fields")
}
func TestCopyProposerSlashings(t *testing.T) {
ps := genProposerSlashings(10)
got := v1alpha1.CopyProposerSlashings(ps)
if !reflect.DeepEqual(got, ps) {
t.Errorf("CopyProposerSlashings() = %v, want %v", got, ps)
}
assert.NotEmpty(t, got, "Copied proposer slashings have empty fields")
}
func TestCopyProposerSlashing(t *testing.T) {
ps := genProposerSlashing()
got := v1alpha1.CopyProposerSlashing(ps)
if !reflect.DeepEqual(got, ps) {
t.Errorf("CopyProposerSlashing() = %v, want %v", got, ps)
}
assert.NotEmpty(t, got, "Copied proposer slashing has empty fields")
}
func TestCopySignedBeaconBlockHeader(t *testing.T) {
sbh := genSignedBeaconBlockHeader()
got := v1alpha1.CopySignedBeaconBlockHeader(sbh)
if !reflect.DeepEqual(got, sbh) {
t.Errorf("CopySignedBeaconBlockHeader() = %v, want %v", got, sbh)
}
assert.NotEmpty(t, got, "Copied signed beacon block header has empty fields")
}
func TestCopyBeaconBlockHeader(t *testing.T) {
bh := genBeaconBlockHeader()
got := v1alpha1.CopyBeaconBlockHeader(bh)
if !reflect.DeepEqual(got, bh) {
t.Errorf("CopyBeaconBlockHeader() = %v, want %v", got, bh)
}
assert.NotEmpty(t, got, "Copied beacon block header has empty fields")
}
func TestCopyDeposits(t *testing.T) {
d := genDeposits(10)
got := v1alpha1.CopyDeposits(d)
if !reflect.DeepEqual(got, d) {
t.Errorf("CopyDeposits() = %v, want %v", got, d)
}
assert.NotEmpty(t, got, "Copied deposits have empty fields")
}
func TestCopyDeposit(t *testing.T) {
d := genDeposit()
got := v1alpha1.CopyDeposit(d)
if !reflect.DeepEqual(got, d) {
t.Errorf("CopyDeposit() = %v, want %v", got, d)
}
assert.NotEmpty(t, got, "Copied deposit has empty fields")
}
func TestCopyDepositData(t *testing.T) {
dd := genDepositData()
got := v1alpha1.CopyDepositData(dd)
if !reflect.DeepEqual(got, dd) {
t.Errorf("CopyDepositData() = %v, want %v", got, dd)
}
assert.NotEmpty(t, got, "Copied deposit data has empty fields")
}
func TestCopySignedVoluntaryExits(t *testing.T) {
sv := genSignedVoluntaryExits(10)
got := v1alpha1.CopySignedVoluntaryExits(sv)
if !reflect.DeepEqual(got, sv) {
t.Errorf("CopySignedVoluntaryExits() = %v, want %v", got, sv)
}
assert.NotEmpty(t, got, "Copied signed voluntary exits have empty fields")
}
func TestCopySignedVoluntaryExit(t *testing.T) {
sv := genSignedVoluntaryExit()
got := v1alpha1.CopySignedVoluntaryExit(sv)
if !reflect.DeepEqual(got, sv) {
t.Errorf("CopySignedVoluntaryExit() = %v, want %v", got, sv)
}
assert.NotEmpty(t, got, "Copied signed voluntary exit has empty fields")
}
func TestCopyValidator(t *testing.T) {
v := genValidator()
@@ -200,16 +100,6 @@ func TestCopySyncCommitteeContribution(t *testing.T) {
assert.NotEmpty(t, got, "Copied sync committee contribution has empty fields")
}
func TestCopySyncAggregate(t *testing.T) {
sa := genSyncAggregate()
got := v1alpha1.CopySyncAggregate(sa)
if !reflect.DeepEqual(got, sa) {
t.Errorf("CopySyncAggregate() = %v, want %v", got, sa)
}
assert.NotEmpty(t, got, "Copied sync aggregate has empty fields")
}
func TestCopyPendingAttestationSlice(t *testing.T) {
tests := []struct {
name string
@@ -428,27 +318,6 @@ func bytes(length int) []byte {
return b
}
func TestCopyBLSToExecutionChanges(t *testing.T) {
changes := genBLSToExecutionChanges(10)
got := v1alpha1.CopyBLSToExecutionChanges(changes)
if !reflect.DeepEqual(got, changes) {
t.Errorf("TestCopyBLSToExecutionChanges() = %v, want %v", got, changes)
}
}
func TestCopyHistoricalSummaries(t *testing.T) {
summaries := []*v1alpha1.HistoricalSummary{
{BlockSummaryRoot: []byte("block summary root 0"), StateSummaryRoot: []byte("state summary root 0")},
{BlockSummaryRoot: []byte("block summary root 1"), StateSummaryRoot: []byte("state summary root 1")},
}
got := v1alpha1.CopyHistoricalSummaries(summaries)
if !reflect.DeepEqual(got, summaries) {
t.Errorf("TestCopyHistoricalSummariesing() = %v, want %v", got, summaries)
}
}
func TestCopySignedBlindedBeaconBlockElectra(t *testing.T) {
sbb := genSignedBlindedBeaconBlockElectra()
@@ -503,33 +372,6 @@ func TestCopyBeaconBlockBodyElectra(t *testing.T) {
}
}
func TestCopyPendingPartialWithdrawals(t *testing.T) {
ppws := genPendingPartialWithdrawals(10)
got := v1alpha1.CopyPendingPartialWithdrawals(ppws)
if !reflect.DeepEqual(got, ppws) {
t.Errorf("TestCopyPendingPartialWithdrawals() = %v, want %v", got, ppws)
}
}
func TestCopyPendingConsolidations(t *testing.T) {
pcs := genPendingConsolidations(10)
got := v1alpha1.CopyPendingConsolidations(pcs)
if !reflect.DeepEqual(got, pcs) {
t.Errorf("TestCopyPendingConsolidations() = %v, want %v", got, pcs)
}
}
func TestCopyPendingBalanceDeposits(t *testing.T) {
pbds := genPendingBalanceDeposits(10)
got := v1alpha1.CopyPendingBalanceDeposits(pbds)
if !reflect.DeepEqual(got, pbds) {
t.Errorf("TestCopyPendingBalanceDeposits() = %v, want %v", got, pbds)
}
}
func genAttestation() *v1alpha1.Attestation {
return &v1alpha1.Attestation{
AggregationBits: bytes(32),

View File

@@ -0,0 +1,24 @@
package eth
// Copy --
func (pw *PendingPartialWithdrawal) Copy() *PendingPartialWithdrawal {
if pw == nil {
return nil
}
return &PendingPartialWithdrawal{
Index: pw.Index,
Amount: pw.Amount,
WithdrawableEpoch: pw.WithdrawableEpoch,
}
}
// Copy --
func (pc *PendingConsolidation) Copy() *PendingConsolidation {
if pc == nil {
return nil
}
return &PendingConsolidation{
SourceIndex: pc.SourceIndex,
TargetIndex: pc.TargetIndex,
}
}

View File

@@ -0,0 +1,12 @@
package eth_test
import (
"testing"
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
)
func TestCopyEip7521Types_Fuzz(t *testing.T) {
fuzzCopies(t, &eth.PendingPartialWithdrawal{})
fuzzCopies(t, &eth.PendingConsolidation{})
}

View File

@@ -0,0 +1,25 @@
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 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)
// TODO: add deep fuzzing and checks for deep not equals
// we should test that modifying the copy doesn't modify the original object
}
})
}