github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/core/state/benchmarks_test.go (about)

     1  package state_test
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
     8  	coreState "github.com/prysmaticlabs/prysm/beacon-chain/core/state"
     9  	iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
    10  	"github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
    11  	pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
    12  	"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
    13  	"github.com/prysmaticlabs/prysm/shared/benchutil"
    14  	"github.com/prysmaticlabs/prysm/shared/params"
    15  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    16  	"google.golang.org/protobuf/proto"
    17  )
    18  
    19  var runAmount = 25
    20  
    21  func BenchmarkExecuteStateTransition_FullBlock(b *testing.B) {
    22  	benchutil.SetBenchmarkConfig()
    23  	beaconState, err := benchutil.PreGenState1Epoch()
    24  	require.NoError(b, err)
    25  	cleanStates := clonedStates(beaconState)
    26  	block, err := benchutil.PreGenFullBlock()
    27  	require.NoError(b, err)
    28  
    29  	b.ResetTimer()
    30  	for i := 0; i < b.N; i++ {
    31  		_, err := coreState.ExecuteStateTransition(context.Background(), cleanStates[i], wrapper.WrappedPhase0SignedBeaconBlock(block))
    32  		require.NoError(b, err)
    33  	}
    34  }
    35  
    36  func BenchmarkExecuteStateTransition_WithCache(b *testing.B) {
    37  	benchutil.SetBenchmarkConfig()
    38  
    39  	beaconState, err := benchutil.PreGenState1Epoch()
    40  	require.NoError(b, err)
    41  	cleanStates := clonedStates(beaconState)
    42  	block, err := benchutil.PreGenFullBlock()
    43  	require.NoError(b, err)
    44  
    45  	// We have to reset slot back to last epoch to hydrate cache. Since
    46  	// some attestations in block are from previous epoch
    47  	currentSlot := beaconState.Slot()
    48  	require.NoError(b, beaconState.SetSlot(beaconState.Slot()-params.BeaconConfig().SlotsPerEpoch))
    49  	require.NoError(b, helpers.UpdateCommitteeCache(beaconState, helpers.CurrentEpoch(beaconState)))
    50  	require.NoError(b, beaconState.SetSlot(currentSlot))
    51  	// Run the state transition once to populate the cache.
    52  	_, err = coreState.ExecuteStateTransition(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(block))
    53  	require.NoError(b, err, "Failed to process block, benchmarks will fail")
    54  
    55  	b.ResetTimer()
    56  	for i := 0; i < b.N; i++ {
    57  		_, err := coreState.ExecuteStateTransition(context.Background(), cleanStates[i], wrapper.WrappedPhase0SignedBeaconBlock(block))
    58  		require.NoError(b, err, "Failed to process block, benchmarks will fail")
    59  	}
    60  }
    61  
    62  func BenchmarkProcessEpoch_2FullEpochs(b *testing.B) {
    63  	benchutil.SetBenchmarkConfig()
    64  	beaconState, err := benchutil.PreGenState2FullEpochs()
    65  	require.NoError(b, err)
    66  
    67  	// We have to reset slot back to last epoch to hydrate cache. Since
    68  	// some attestations in block are from previous epoch
    69  	currentSlot := beaconState.Slot()
    70  	require.NoError(b, beaconState.SetSlot(beaconState.Slot()-params.BeaconConfig().SlotsPerEpoch))
    71  	require.NoError(b, helpers.UpdateCommitteeCache(beaconState, helpers.CurrentEpoch(beaconState)))
    72  	require.NoError(b, beaconState.SetSlot(currentSlot))
    73  
    74  	b.ResetTimer()
    75  	for i := 0; i < b.N; i++ {
    76  		// ProcessEpochPrecompute is the optimized version of process epoch. It's enabled by default
    77  		// at run time.
    78  		_, err := coreState.ProcessEpochPrecompute(context.Background(), beaconState.Copy())
    79  		require.NoError(b, err)
    80  	}
    81  }
    82  
    83  func BenchmarkHashTreeRoot_FullState(b *testing.B) {
    84  	beaconState, err := benchutil.PreGenState2FullEpochs()
    85  	require.NoError(b, err)
    86  
    87  	b.ResetTimer()
    88  	for i := 0; i < b.N; i++ {
    89  		_, err := beaconState.HashTreeRoot(context.Background())
    90  		require.NoError(b, err)
    91  	}
    92  }
    93  
    94  func BenchmarkHashTreeRootState_FullState(b *testing.B) {
    95  	beaconState, err := benchutil.PreGenState2FullEpochs()
    96  	require.NoError(b, err)
    97  
    98  	ctx := context.Background()
    99  
   100  	// Hydrate the HashTreeRootState cache.
   101  	_, err = beaconState.HashTreeRoot(ctx)
   102  	require.NoError(b, err)
   103  
   104  	b.ResetTimer()
   105  	for i := 0; i < b.N; i++ {
   106  		_, err := beaconState.HashTreeRoot(ctx)
   107  		require.NoError(b, err)
   108  	}
   109  }
   110  
   111  func BenchmarkMarshalState_FullState(b *testing.B) {
   112  	beaconState, err := benchutil.PreGenState2FullEpochs()
   113  	require.NoError(b, err)
   114  	natState, err := v1.ProtobufBeaconState(beaconState.InnerStateUnsafe())
   115  	require.NoError(b, err)
   116  	b.Run("Proto_Marshal", func(b *testing.B) {
   117  		b.ResetTimer()
   118  		b.ReportAllocs()
   119  		for i := 0; i < b.N; i++ {
   120  			_, err := proto.Marshal(natState)
   121  			require.NoError(b, err)
   122  		}
   123  	})
   124  
   125  	b.Run("Fast_SSZ_Marshal", func(b *testing.B) {
   126  		b.ResetTimer()
   127  		b.ReportAllocs()
   128  		for i := 0; i < b.N; i++ {
   129  			_, err := natState.MarshalSSZ()
   130  			require.NoError(b, err)
   131  		}
   132  	})
   133  }
   134  
   135  func BenchmarkUnmarshalState_FullState(b *testing.B) {
   136  	beaconState, err := benchutil.PreGenState2FullEpochs()
   137  	require.NoError(b, err)
   138  	natState, err := v1.ProtobufBeaconState(beaconState.InnerStateUnsafe())
   139  	require.NoError(b, err)
   140  	protoObject, err := proto.Marshal(natState)
   141  	require.NoError(b, err)
   142  	sszObject, err := natState.MarshalSSZ()
   143  	require.NoError(b, err)
   144  
   145  	b.Run("Proto_Unmarshal", func(b *testing.B) {
   146  		b.ResetTimer()
   147  		b.ReportAllocs()
   148  		for i := 0; i < b.N; i++ {
   149  			require.NoError(b, proto.Unmarshal(protoObject, &pb.BeaconState{}))
   150  		}
   151  	})
   152  
   153  	b.Run("Fast_SSZ_Unmarshal", func(b *testing.B) {
   154  		b.ResetTimer()
   155  		b.ReportAllocs()
   156  		for i := 0; i < b.N; i++ {
   157  			sszState := &pb.BeaconState{}
   158  			require.NoError(b, sszState.UnmarshalSSZ(sszObject))
   159  		}
   160  	})
   161  }
   162  
   163  func clonedStates(beaconState iface.BeaconState) []iface.BeaconState {
   164  	clonedStates := make([]iface.BeaconState, runAmount)
   165  	for i := 0; i < runAmount; i++ {
   166  		clonedStates[i] = beaconState.Copy()
   167  	}
   168  	return clonedStates
   169  }