1
+ use bls:: { FixedBytesExtended , Hash256 , PublicKeyBytes } ;
2
+ use criterion:: { criterion_group, criterion_main, BatchSize , Criterion } ;
3
+ use rand:: Rng ;
4
+ use ssz:: Decode ;
5
+ use std:: num:: NonZeroUsize ;
6
+ use store:: state_cache:: StateCache ;
7
+
8
+ use types:: {
9
+ BeaconState , ChainSpec , Epoch , Eth1Data , EthSpec , MainnetEthSpec as E , Slot , Validator ,
10
+ } ;
11
+
12
+ fn build_state (
13
+ spec : & ChainSpec ,
14
+ slot : Slot ,
15
+ validator_count : usize ,
16
+ rng : & mut impl Rng ,
17
+ ) -> BeaconState < E > {
18
+ let genesis_time = 0 ;
19
+ let eth1_data = Eth1Data :: default ( ) ;
20
+ let mut state = BeaconState :: < E > :: new ( genesis_time, eth1_data, spec) ;
21
+
22
+ for _ in 0 ..validator_count {
23
+ append_validator ( & mut state, rng) ;
24
+ }
25
+
26
+ * state. slot_mut ( ) = slot;
27
+ state. latest_block_header_mut ( ) . slot = slot;
28
+ state. apply_pending_mutations ( ) . unwrap ( ) ;
29
+ state
30
+ }
31
+
32
+ fn append_validator ( state : & mut BeaconState < E > , mut rng : & mut impl Rng ) {
33
+ state
34
+ . balances_mut ( )
35
+ . push ( 32_000_000_000 + rng. random_range ( 1 ..=1_000_000_000 ) )
36
+ . unwrap ( ) ;
37
+ if let Ok ( inactivity_scores) = state. inactivity_scores_mut ( ) {
38
+ inactivity_scores. push ( 0 ) . unwrap ( ) ;
39
+ }
40
+ state
41
+ . validators_mut ( )
42
+ . push ( rand_validator ( & mut rng) )
43
+ . unwrap ( ) ;
44
+ }
45
+
46
+ fn rand_validator ( rng : & mut impl Rng ) -> Validator {
47
+ let mut pubkey = [ 0u8 ; 48 ] ;
48
+ rng. fill_bytes ( & mut pubkey) ;
49
+ let withdrawal_credentials: [ u8 ; 32 ] = rng. random ( ) ;
50
+
51
+ Validator {
52
+ pubkey : PublicKeyBytes :: from_ssz_bytes ( & pubkey) . unwrap ( ) ,
53
+ withdrawal_credentials : withdrawal_credentials. into ( ) ,
54
+ slashed : false ,
55
+ effective_balance : 32_000_000_000 ,
56
+ activation_eligibility_epoch : Epoch :: max_value ( ) ,
57
+ activation_epoch : Epoch :: max_value ( ) ,
58
+ exit_epoch : Epoch :: max_value ( ) ,
59
+ withdrawable_epoch : Epoch :: max_value ( ) ,
60
+ }
61
+ }
62
+
63
+ pub fn all_benches ( c : & mut Criterion ) {
64
+ let spec = E :: default_spec ( ) ;
65
+ let mut rng = rand:: rng ( ) ;
66
+ let num_states = 20 ;
67
+ let validator_count = 1024 ;
68
+
69
+ let states: Vec < ( Hash256 , Hash256 , BeaconState < E > ) > = ( 0 ..num_states)
70
+ . map ( |i| {
71
+ let slot = Slot :: new ( i as u64 ) ;
72
+ let state = build_state ( & spec, slot, validator_count, & mut rng) ;
73
+ let root = Hash256 :: from_low_u64_le ( i as u64 + 1 ) ;
74
+ ( root, root, state)
75
+ } ) . collect ( ) ;
76
+
77
+ let capacity = NonZeroUsize :: new ( num_states) . unwrap ( ) ;
78
+ let headroom = NonZeroUsize :: new ( 1 ) . unwrap ( ) ;
79
+ let hdiff_capacity = NonZeroUsize :: new ( 1 ) . unwrap ( ) ;
80
+
81
+ c. bench_function ( "state_cache_insert_without_memory_limit" , |b| {
82
+ b. iter_batched (
83
+ || StateCache :: new ( capacity, headroom, hdiff_capacity, usize:: MAX ) ,
84
+ |mut cache| {
85
+ for ( state_root, block_root, state) in & states {
86
+ cache. put_state ( * state_root, * block_root, state) . unwrap ( ) ;
87
+ }
88
+ } ,
89
+ BatchSize :: SmallInput ,
90
+ ) ;
91
+ } ) ;
92
+
93
+ let low_max_bytes = 1_000_000 ;
94
+ c. bench_function ( "state_cache_insert_with_memory_limit" , |b| {
95
+ b. iter_batched (
96
+ || StateCache :: new ( capacity, headroom, hdiff_capacity, low_max_bytes) ,
97
+ |mut cache| {
98
+ for ( state_root, block_root, state) in & states {
99
+ cache. put_state ( * state_root, * block_root, state) . unwrap ( ) ;
100
+ }
101
+ assert ! ( cache. cached_bytes( ) <= cache. max_cached_bytes( ) ) ;
102
+ } ,
103
+ BatchSize :: SmallInput ,
104
+ ) ;
105
+ } ) ;
106
+
107
+ }
108
+
109
+ criterion_group ! {
110
+ name = benches;
111
+ config = Criterion :: default ( ) . sample_size( 10 ) ;
112
+ targets = all_benches
113
+ }
114
+ criterion_main ! ( benches) ;
0 commit comments