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  })