github.com/MetalBlockchain/metalgo@v1.11.9/snow/consensus/snowball/parameters_test.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package snowball 5 6 import ( 7 "testing" 8 9 "github.com/stretchr/testify/require" 10 ) 11 12 func TestParametersVerify(t *testing.T) { 13 tests := []struct { 14 name string 15 params Parameters 16 expectedError error 17 }{ 18 { 19 name: "valid", 20 params: Parameters{ 21 K: 1, 22 AlphaPreference: 1, 23 AlphaConfidence: 1, 24 Beta: 1, 25 ConcurrentRepolls: 1, 26 OptimalProcessing: 1, 27 MaxOutstandingItems: 1, 28 MaxItemProcessingTime: 1, 29 }, 30 expectedError: nil, 31 }, 32 { 33 name: "invalid K", 34 params: Parameters{ 35 K: 0, 36 AlphaPreference: 1, 37 AlphaConfidence: 1, 38 Beta: 1, 39 ConcurrentRepolls: 1, 40 OptimalProcessing: 1, 41 MaxOutstandingItems: 1, 42 MaxItemProcessingTime: 1, 43 }, 44 expectedError: ErrParametersInvalid, 45 }, 46 { 47 name: "invalid AlphaPreference 1", 48 params: Parameters{ 49 K: 2, 50 AlphaPreference: 1, 51 AlphaConfidence: 1, 52 Beta: 1, 53 ConcurrentRepolls: 1, 54 OptimalProcessing: 1, 55 MaxOutstandingItems: 1, 56 MaxItemProcessingTime: 1, 57 }, 58 expectedError: ErrParametersInvalid, 59 }, 60 { 61 name: "invalid AlphaPreference 0", 62 params: Parameters{ 63 K: 1, 64 AlphaPreference: 0, 65 AlphaConfidence: 1, 66 Beta: 1, 67 ConcurrentRepolls: 1, 68 OptimalProcessing: 1, 69 MaxOutstandingItems: 1, 70 MaxItemProcessingTime: 1, 71 }, 72 expectedError: ErrParametersInvalid, 73 }, 74 { 75 name: "invalid AlphaConfidence", 76 params: Parameters{ 77 K: 3, 78 AlphaPreference: 3, 79 AlphaConfidence: 2, 80 Beta: 1, 81 ConcurrentRepolls: 1, 82 OptimalProcessing: 1, 83 MaxOutstandingItems: 1, 84 MaxItemProcessingTime: 1, 85 }, 86 expectedError: ErrParametersInvalid, 87 }, 88 { 89 name: "invalid beta", 90 params: Parameters{ 91 K: 1, 92 AlphaPreference: 1, 93 AlphaConfidence: 1, 94 Beta: 0, 95 ConcurrentRepolls: 1, 96 OptimalProcessing: 1, 97 MaxOutstandingItems: 1, 98 MaxItemProcessingTime: 1, 99 }, 100 expectedError: ErrParametersInvalid, 101 }, 102 { 103 name: "first half fun alphaConfidence", 104 params: Parameters{ 105 K: 30, 106 AlphaPreference: 28, 107 AlphaConfidence: 30, 108 Beta: 2, 109 ConcurrentRepolls: 1, 110 OptimalProcessing: 1, 111 MaxOutstandingItems: 1, 112 MaxItemProcessingTime: 1, 113 }, 114 expectedError: nil, 115 }, 116 { 117 name: "second half fun alphaConfidence", 118 params: Parameters{ 119 K: 3, 120 AlphaPreference: 2, 121 AlphaConfidence: 3, 122 Beta: 2, 123 ConcurrentRepolls: 1, 124 OptimalProcessing: 1, 125 MaxOutstandingItems: 1, 126 MaxItemProcessingTime: 1, 127 }, 128 expectedError: nil, 129 }, 130 { 131 name: "fun invalid alphaConfidence", 132 params: Parameters{ 133 K: 1, 134 AlphaPreference: 28, 135 AlphaConfidence: 3, 136 Beta: 2, 137 ConcurrentRepolls: 1, 138 OptimalProcessing: 1, 139 MaxOutstandingItems: 1, 140 MaxItemProcessingTime: 1, 141 }, 142 expectedError: ErrParametersInvalid, 143 }, 144 { 145 name: "too few ConcurrentRepolls", 146 params: Parameters{ 147 K: 1, 148 AlphaPreference: 1, 149 AlphaConfidence: 1, 150 Beta: 1, 151 ConcurrentRepolls: 0, 152 OptimalProcessing: 1, 153 MaxOutstandingItems: 1, 154 MaxItemProcessingTime: 1, 155 }, 156 expectedError: ErrParametersInvalid, 157 }, 158 { 159 name: "too many ConcurrentRepolls", 160 params: Parameters{ 161 K: 1, 162 AlphaPreference: 1, 163 AlphaConfidence: 1, 164 Beta: 1, 165 ConcurrentRepolls: 2, 166 OptimalProcessing: 1, 167 MaxOutstandingItems: 1, 168 MaxItemProcessingTime: 1, 169 }, 170 expectedError: ErrParametersInvalid, 171 }, 172 { 173 name: "invalid OptimalProcessing", 174 params: Parameters{ 175 K: 1, 176 AlphaPreference: 1, 177 AlphaConfidence: 1, 178 Beta: 1, 179 ConcurrentRepolls: 1, 180 OptimalProcessing: 0, 181 MaxOutstandingItems: 1, 182 MaxItemProcessingTime: 1, 183 }, 184 expectedError: ErrParametersInvalid, 185 }, 186 { 187 name: "invalid MaxOutstandingItems", 188 params: Parameters{ 189 K: 1, 190 AlphaPreference: 1, 191 AlphaConfidence: 1, 192 Beta: 1, 193 ConcurrentRepolls: 1, 194 OptimalProcessing: 1, 195 MaxOutstandingItems: 0, 196 MaxItemProcessingTime: 1, 197 }, 198 expectedError: ErrParametersInvalid, 199 }, 200 { 201 name: "invalid MaxItemProcessingTime", 202 params: Parameters{ 203 K: 1, 204 AlphaPreference: 1, 205 AlphaConfidence: 1, 206 Beta: 1, 207 ConcurrentRepolls: 1, 208 OptimalProcessing: 1, 209 MaxOutstandingItems: 1, 210 MaxItemProcessingTime: 0, 211 }, 212 expectedError: ErrParametersInvalid, 213 }, 214 } 215 for _, test := range tests { 216 t.Run(test.name, func(t *testing.T) { 217 err := test.params.Verify() 218 require.ErrorIs(t, err, test.expectedError) 219 }) 220 } 221 } 222 223 func TestParametersMinPercentConnectedHealthy(t *testing.T) { 224 tests := []struct { 225 name string 226 params Parameters 227 expectedMinPercentConnected float64 228 }{ 229 { 230 name: "default", 231 params: DefaultParameters, 232 expectedMinPercentConnected: 0.8, 233 }, 234 { 235 name: "custom", 236 params: Parameters{ 237 K: 5, 238 AlphaConfidence: 4, 239 }, 240 expectedMinPercentConnected: 0.84, 241 }, 242 { 243 name: "custom", 244 params: Parameters{ 245 K: 1001, 246 AlphaConfidence: 501, 247 }, 248 expectedMinPercentConnected: 0.6, 249 }, 250 } 251 252 for _, tt := range tests { 253 t.Run(tt.name, func(t *testing.T) { 254 minStake := tt.params.MinPercentConnectedHealthy() 255 require.InEpsilon(t, tt.expectedMinPercentConnected, minStake, .001) 256 }) 257 } 258 }