github.com/kotalco/kotal@v0.3.0/apis/ethereum/v1alpha1/genesis_validation_test.go (about) 1 package v1alpha1 2 3 import ( 4 "fmt" 5 6 "github.com/kotalco/kotal/apis/shared" 7 . "github.com/onsi/ginkgo/v2" 8 . "github.com/onsi/gomega" 9 "k8s.io/apimachinery/pkg/util/validation/field" 10 ) 11 12 var _ = Describe("Genesis Block validation", func() { 13 14 createCases := []struct { 15 Title string 16 Genesis *Genesis 17 Errors field.ErrorList 18 }{ 19 { 20 Title: "using mainnet chain id", 21 Genesis: &Genesis{ 22 ChainID: 1, 23 NetworkID: 55555, 24 }, 25 Errors: field.ErrorList{ 26 { 27 Type: field.ErrorTypeInvalid, 28 Field: "spec.genesis.chainId", 29 BadValue: "1", 30 Detail: "can't use chain id of mainnet network to avoid tx replay", 31 }, 32 }, 33 }, 34 { 35 Title: "bad fork activation order", 36 Genesis: &Genesis{ 37 ChainID: 55555, 38 NetworkID: 55555, 39 Ethash: &Ethash{}, 40 Forks: &Forks{ 41 EIP150: 1, 42 Homestead: 2, 43 }, 44 }, 45 Errors: field.ErrorList{ 46 { 47 Type: field.ErrorTypeInvalid, 48 Field: "spec.genesis.forks.eip150", 49 BadValue: "1", 50 Detail: "Fork eip150 can't be activated (at block 1) before fork homestead (at block 2)", 51 }, 52 }, 53 }, 54 { 55 Title: "consensus configuration is missing", 56 Genesis: &Genesis{ 57 ChainID: 4444, 58 NetworkID: 4444, 59 }, 60 Errors: []*field.Error{ 61 { 62 Type: field.ErrorTypeInvalid, 63 Field: "spec.genesis", 64 BadValue: "", 65 Detail: "consensus configuration (ethash, clique, or ibft2) is missing", 66 }, 67 }, 68 }, 69 { 70 Title: "multiple consensus configurations are used", 71 Genesis: &Genesis{ 72 ChainID: 4444, 73 NetworkID: 4444, 74 Ethash: &Ethash{}, 75 Clique: &Clique{}, 76 }, 77 Errors: []*field.Error{ 78 { 79 Type: field.ErrorTypeInvalid, 80 Field: "spec.genesis", 81 BadValue: "", 82 Detail: "multiple consensus configurations (clique, ethash) are enabled", 83 }, 84 }, 85 }, 86 { 87 Title: "reserved account is used", 88 Genesis: &Genesis{ 89 ChainID: 4444, 90 NetworkID: 4444, 91 Ethash: &Ethash{}, 92 Accounts: []Account{ 93 { 94 Address: shared.EthereumAddress("0x0000000000000000000000000000000000000015"), 95 Balance: HexString("0xffffff"), 96 }, 97 }, 98 }, 99 Errors: []*field.Error{ 100 { 101 Type: field.ErrorTypeInvalid, 102 Field: "spec.genesis.accounts", 103 BadValue: "0x0000000000000000000000000000000000000015", 104 Detail: "reserved account is used", 105 }, 106 }, 107 }, 108 } 109 110 updateCases := []struct { 111 Title string 112 OldGenesis *Genesis 113 NewGenesis *Genesis 114 Errors field.ErrorList 115 }{ 116 { 117 Title: "updating coinbase", 118 OldGenesis: &Genesis{ 119 NetworkID: 55555, 120 ChainID: 55555, 121 Ethash: &Ethash{}, 122 Forks: &Forks{}, 123 }, 124 NewGenesis: &Genesis{ 125 NetworkID: 55555, 126 ChainID: 55555, 127 Coinbase: "0x0000000000000000000000000000000000000001", 128 Ethash: &Ethash{}, 129 Forks: &Forks{}, 130 }, 131 Errors: []*field.Error{ 132 { 133 Type: field.ErrorTypeInvalid, 134 Field: "spec.genesis.coinbase", 135 BadValue: shared.EthereumAddress("0x0000000000000000000000000000000000000001"), 136 Detail: "field is immutable", 137 }, 138 }, 139 }, 140 { 141 Title: "updating difficulty", 142 OldGenesis: &Genesis{ 143 NetworkID: 55555, 144 ChainID: 55555, 145 Ethash: &Ethash{}, 146 Forks: &Forks{}, 147 }, 148 NewGenesis: &Genesis{ 149 NetworkID: 55555, 150 ChainID: 55555, 151 Difficulty: "0xffff", 152 Ethash: &Ethash{}, 153 Forks: &Forks{}, 154 }, 155 Errors: []*field.Error{ 156 { 157 Type: field.ErrorTypeInvalid, 158 Field: "spec.genesis.difficulty", 159 BadValue: HexString("0xffff"), 160 Detail: "field is immutable", 161 }, 162 }, 163 }, 164 { 165 Title: "updating mixHash", 166 OldGenesis: &Genesis{ 167 NetworkID: 55555, 168 ChainID: 55555, 169 Ethash: &Ethash{}, 170 Forks: &Forks{}, 171 }, 172 NewGenesis: &Genesis{ 173 NetworkID: 55555, 174 ChainID: 55555, 175 MixHash: Hash("0x00000000000000000000000000000000000000000000000000000000000000ff"), 176 Ethash: &Ethash{}, 177 Forks: &Forks{}, 178 }, 179 Errors: []*field.Error{ 180 { 181 Type: field.ErrorTypeInvalid, 182 Field: "spec.genesis.mixHash", 183 BadValue: Hash("0x00000000000000000000000000000000000000000000000000000000000000ff"), 184 Detail: "field is immutable", 185 }, 186 }, 187 }, 188 { 189 Title: "updating gasLimit", 190 OldGenesis: &Genesis{ 191 NetworkID: 55555, 192 ChainID: 55555, 193 Ethash: &Ethash{}, 194 Forks: &Forks{}, 195 }, 196 NewGenesis: &Genesis{ 197 NetworkID: 55555, 198 ChainID: 55555, 199 GasLimit: HexString("0x47bfff"), 200 Ethash: &Ethash{}, 201 Forks: &Forks{}, 202 }, 203 Errors: []*field.Error{ 204 { 205 Type: field.ErrorTypeInvalid, 206 Field: "spec.genesis.gasLimit", 207 BadValue: HexString("0x47bfff"), 208 Detail: "field is immutable", 209 }, 210 }, 211 }, 212 { 213 Title: "updating nonce", 214 OldGenesis: &Genesis{ 215 NetworkID: 55555, 216 ChainID: 55555, 217 Ethash: &Ethash{}, 218 Forks: &Forks{}, 219 }, 220 NewGenesis: &Genesis{ 221 NetworkID: 55555, 222 ChainID: 55555, 223 Nonce: HexString("0x1"), 224 Ethash: &Ethash{}, 225 Forks: &Forks{}, 226 }, 227 Errors: []*field.Error{ 228 { 229 Type: field.ErrorTypeInvalid, 230 Field: "spec.genesis.nonce", 231 BadValue: HexString("0x1"), 232 Detail: "field is immutable", 233 }, 234 }, 235 }, 236 { 237 Title: "updating timestamp", 238 OldGenesis: &Genesis{ 239 NetworkID: 55555, 240 ChainID: 55555, 241 Ethash: &Ethash{}, 242 Forks: &Forks{}, 243 }, 244 NewGenesis: &Genesis{ 245 NetworkID: 55555, 246 ChainID: 55555, 247 Timestamp: HexString("0x1"), 248 Ethash: &Ethash{}, 249 Forks: &Forks{}, 250 }, 251 Errors: []*field.Error{ 252 { 253 Type: field.ErrorTypeInvalid, 254 Field: "spec.genesis.timestamp", 255 BadValue: HexString("0x1"), 256 Detail: "field is immutable", 257 }, 258 }, 259 }, 260 { 261 Title: "updating accounts", 262 OldGenesis: &Genesis{ 263 NetworkID: 55555, 264 ChainID: 55555, 265 Ethash: &Ethash{}, 266 Forks: &Forks{}, 267 Accounts: []Account{ 268 { 269 Address: shared.EthereumAddress("0xB1368D309179D8E7f25B34398e4cF9D9dEFdC75C"), 270 Balance: HexString("0xffffff"), 271 }, 272 }, 273 }, 274 NewGenesis: &Genesis{ 275 NetworkID: 55555, 276 ChainID: 55555, 277 Ethash: &Ethash{}, 278 Forks: &Forks{}, 279 Accounts: []Account{ 280 { 281 Address: shared.EthereumAddress("0xB1368D309179D8E7f25B34398e4cF9D9dEFdC75C"), 282 Balance: HexString("0x111111"), // change account balance 283 }, 284 }, 285 }, 286 Errors: []*field.Error{ 287 { 288 Type: field.ErrorTypeInvalid, 289 Field: "spec.genesis.accounts", 290 BadValue: "", 291 Detail: "field is immutable", 292 }, 293 }, 294 }, 295 } 296 297 Context("While creating genesis", func() { 298 for _, c := range createCases { 299 func() { 300 cc := c 301 It(fmt.Sprintf("Should validate %s", cc.Title), func() { 302 cc.Genesis.Default() 303 304 err := cc.Genesis.ValidateCreate() 305 306 Expect(err).To(ContainElements(cc.Errors)) 307 }) 308 }() 309 } 310 }) 311 312 Context("While updating genesis", func() { 313 for _, c := range updateCases { 314 func() { 315 cc := c 316 It(fmt.Sprintf("Should validate %s", cc.Title), func() { 317 cc.OldGenesis.Default() 318 cc.NewGenesis.Default() 319 320 err := cc.NewGenesis.ValidateUpdate(cc.OldGenesis) 321 322 Expect(err).To(ContainElements(cc.Errors)) 323 }) 324 }() 325 } 326 }) 327 328 })