Skip to content

Commit

Permalink
moving cloners to beacon_block.go and adding fuzzing (#14255)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
james-prysm authored Jul 23, 2024
1 parent 4d823ac commit b108d5b
Show file tree
Hide file tree
Showing 20 changed files with 336 additions and 484 deletions.
3 changes: 1 addition & 2 deletions beacon-chain/core/blocks/eth1_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -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++
}
}
Expand Down
2 changes: 1 addition & 1 deletion beacon-chain/core/blocks/eth1_data_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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[:]
Expand Down Expand Up @@ -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[:]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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[:]
Expand Down Expand Up @@ -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[:]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ func (b *BeaconState) pendingBalanceDepositsVal() []*ethpb.PendingBalanceDeposit
return nil
}

return ethpb.CopyPendingBalanceDeposits(b.pendingBalanceDeposits)
return ethpb.CopySlice(b.pendingBalanceDeposits)
}
2 changes: 1 addition & 1 deletion beacon-chain/state/state-native/getters_consolidation.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,5 @@ func (b *BeaconState) pendingConsolidationsVal() []*ethpb.PendingConsolidation {
return nil
}

return ethpb.CopyPendingConsolidations(b.pendingConsolidations)
return ethpb.CopySlice(b.pendingConsolidations)
}
4 changes: 2 additions & 2 deletions beacon-chain/state/state-native/getters_eth1.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion beacon-chain/state/state-native/getters_misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
2 changes: 1 addition & 1 deletion beacon-chain/state/state-native/getters_withdrawal.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion beacon-chain/state/state-native/setters_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/deposit/deposit.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
5 changes: 5 additions & 0 deletions proto/prysm/v1alpha1/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 = [
Expand Down
21 changes: 1 addition & 20 deletions proto/prysm/v1alpha1/attestation_fuzz_test.go
Original file line number Diff line number Diff line change
@@ -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{})
Expand All @@ -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
}
})
}
156 changes: 156 additions & 0 deletions proto/prysm/v1alpha1/beacon_block.go
Original file line number Diff line number Diff line change
@@ -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,
}
}
23 changes: 23 additions & 0 deletions proto/prysm/v1alpha1/beacon_block_fuzz_test.go
Original file line number Diff line number Diff line change
@@ -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{})
}
Loading

0 comments on commit b108d5b

Please sign in to comment.