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 }