diff --git a/x/evm/types/params_test.go b/x/evm/types/params_test.go index 6312838be0..2b913af6a5 100644 --- a/x/evm/types/params_test.go +++ b/x/evm/types/params_test.go @@ -10,11 +10,6 @@ import ( "github.com/stretchr/testify/require" ) -const ( - validEthAddress = "0xc0ffee254729296a45a3885639AC7E10F9d54979" - invalidEthAddress = "0xc0ffee254729296a45a3885639AC7E10F9d5497" -) - func TestParamsValidate(t *testing.T) { extraEips := []int64{2929, 1884, 1344} testCases := []struct { @@ -60,34 +55,212 @@ func TestParamsValidate(t *testing.T) { }, expError: true, }, + } + + for _, tc := range testCases { + err := tc.getParams().Validate() + + if tc.expError { + require.Error(t, err, tc.name) + } else { + require.NoError(t, err, tc.name) + } + } +} + +func TestEnabledPrecompilesAddressCorrectness(t *testing.T) { + const ( + validEthAddress = "0xc0ffee254729296a45a3885639AC7E10F9d54979" + invalidEthAddress = "0xc0ffee254729296a45a3885639AC7E10F9d5497" + ) + + testCases := []struct { + name string + getParams func() Params + errorMsg string + }{ { - name: "valid enabled precompiles", + name: "failure: empty address", getParams: func() Params { params := DefaultParams() - params.EnabledPrecompiles = []string{validEthAddress} + params.EnabledPrecompiles = []string{""} return params }, - expError: false, + errorMsg: "invalid hex address", }, { - name: "invalid enabled precompiles", + name: "failure: invalid address #1", getParams: func() Params { params := DefaultParams() params.EnabledPrecompiles = []string{invalidEthAddress} return params }, - expError: true, + errorMsg: "invalid hex address", + }, + { + name: "failure: invalid address #2", + getParams: func() Params { + params := DefaultParams() + params.EnabledPrecompiles = []string{validEthAddress, invalidEthAddress} + return params + }, + errorMsg: "invalid hex address", + }, + { + name: "success: pass nil as enabled precompiles", + getParams: func() Params { + params := DefaultParams() + params.EnabledPrecompiles = nil + return params + }, + errorMsg: "", + }, + { + name: "success: pass empty slice as enabled precompiles", + getParams: func() Params { + params := DefaultParams() + params.EnabledPrecompiles = []string{} + return params + }, + errorMsg: "", + }, + { + name: "success: valid address", + getParams: func() Params { + params := DefaultParams() + params.EnabledPrecompiles = []string{validEthAddress} + return params + }, + errorMsg: "", }, } for _, tc := range testCases { - err := tc.getParams().Validate() + t.Run(tc.name, func(t *testing.T) { + err := tc.getParams().Validate() - if tc.expError { - require.Error(t, err, tc.name) - } else { - require.NoError(t, err, tc.name) - } + if tc.errorMsg == "" { + require.NoError(t, err, tc.name) + } else { + require.ErrorContains(t, err, tc.errorMsg, tc.name) + } + }) + } +} + +func TestEnabledPrecompilesOrderInBytesRepr(t *testing.T) { + const ( + addr1 = "0x1000000000000000000000000000000000000000" + addr2 = "0x2000000000000000000000000000000000000000" + + // NOTE: we sort in bytes representation, so proper order will be []string{mixedCaseAddr, upperCaseAddr}, + // and it differs from lexicographically sorted strings + upperCaseAddr = "0xAB00000000000000000000000000000000000000" + mixedCaseAddr = "0xaA00000000000000000000000000000000000000" + ) + + testCases := []struct { + name string + getParams func() Params + errorMsg string + }{ + { + name: "success: addresses are sorted", + getParams: func() Params { + params := DefaultParams() + params.EnabledPrecompiles = []string{addr1, addr2} + return params + }, + errorMsg: "", + }, + { + name: "failure: addresses are in reverse order", + getParams: func() Params { + params := DefaultParams() + params.EnabledPrecompiles = []string{addr2, addr1} + return params + }, + errorMsg: "enabled precompiles are not sorted", + }, + { + name: "success: addresses are sorted in bytes representation", + getParams: func() Params { + params := DefaultParams() + params.EnabledPrecompiles = []string{mixedCaseAddr, upperCaseAddr} + return params + }, + errorMsg: "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := tc.getParams().Validate() + + if tc.errorMsg == "" { + require.NoError(t, err, tc.name) + } else { + require.ErrorContains(t, err, tc.errorMsg, tc.name) + } + }) + } +} + +func TestEnabledPrecompilesUniquenessInBytesRepr(t *testing.T) { + const ( + addr1 = "0x1000000000000000000000000000000000000000" + addr2 = "0x2000000000000000000000000000000000000000" + + // NOTE: we check uniqueness in bytes representation, so lowerCaseAddr and mixedCaseAddr are the same, + // despite it differs in string representation + lowerCaseAddr = "0xab00000000000000000000000000000000000000" + mixedCaseAddr = "0xAb00000000000000000000000000000000000000" + ) + + testCases := []struct { + name string + getParams func() Params + errorMsg string + }{ + { + name: "success: addresses are unique", + getParams: func() Params { + params := DefaultParams() + params.EnabledPrecompiles = []string{addr1, addr2} + return params + }, + errorMsg: "", + }, + { + name: "failure: addresses are not unique", + getParams: func() Params { + params := DefaultParams() + params.EnabledPrecompiles = []string{addr1, addr1} + return params + }, + errorMsg: "enabled precompiles are not unique", + }, + { + name: "failure: addresses are not unique in bytes representation", + getParams: func() Params { + params := DefaultParams() + params.EnabledPrecompiles = []string{lowerCaseAddr, mixedCaseAddr} + return params + }, + errorMsg: "enabled precompiles are not unique", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := tc.getParams().Validate() + + if tc.errorMsg == "" { + require.NoError(t, err, tc.name) + } else { + require.ErrorContains(t, err, tc.errorMsg, tc.name) + } + }) } } @@ -106,24 +279,6 @@ func TestParamsValidatePriv(t *testing.T) { require.NoError(t, validateBool(true)) require.Error(t, validateEIPs("")) require.NoError(t, validateEIPs([]int64{1884})) - - require.Error(t, validateEnabledPrecompiles([]string{""})) - require.Error(t, validateEnabledPrecompiles([]string{invalidEthAddress})) - require.Error(t, validateEnabledPrecompiles([]string{validEthAddress, invalidEthAddress})) - require.NoError(t, validateEnabledPrecompiles(nil)) - require.NoError(t, validateEnabledPrecompiles([]string{})) - require.NoError(t, validateEnabledPrecompiles([]string{validEthAddress})) - - addr1 := "0x1000000000000000000000000000000000000000" - addr2 := "0x2000000000000000000000000000000000000000" - - // check if sorted - require.NoError(t, validateEnabledPrecompiles([]string{addr1, addr2})) - require.Error(t, validateEnabledPrecompiles([]string{addr2, addr1})) - - // check if unique - require.NoError(t, validateEnabledPrecompiles([]string{addr1, addr2})) - require.Error(t, validateEnabledPrecompiles([]string{addr1, addr1})) } func TestValidateChainConfig(t *testing.T) { @@ -244,91 +399,3 @@ func TestCheckIfEnabledPrecompilesAreRegistered(t *testing.T) { }) } } - -func TestCheckIfSortedInBytesRepr(t *testing.T) { - addr1 := common.HexToAddress("0x1000000000000000000000000000000000000000") - addr2 := common.HexToAddress("0x2000000000000000000000000000000000000000") - - // NOTE: we sort in bytes representation, so proper order will be []string{mixedCaseAddr, upperCaseAddr}, - // and it differs from lexicographically sorted strings - upperCaseAddr := common.HexToAddress("0xAB00000000000000000000000000000000000000") - mixedCaseAddr := common.HexToAddress("0xaA00000000000000000000000000000000000000") - - testCases := []struct { - name string - addrs []common.Address - sorted bool - }{ - { - name: "success: addresses are sorted", - addrs: []common.Address{addr1, addr2}, - sorted: true, - }, - { - name: "failure: addresses are in reverse order", - addrs: []common.Address{addr2, addr1}, - sorted: false, - }, - { - name: "success: addresses are sorted in bytes representation", - addrs: []common.Address{mixedCaseAddr, upperCaseAddr}, - sorted: true, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - err := checkIfSortedInBytesRepr(tc.addrs) - - if tc.sorted { - require.NoError(t, err, tc.name) - } else { - require.Error(t, err, tc.name) - } - }) - } -} - -func TestCheckIfUniqueInBytesRepr(t *testing.T) { - addr1 := common.HexToAddress("0x1000000000000000000000000000000000000000") - addr2 := common.HexToAddress("0x2000000000000000000000000000000000000000") - - // NOTE: we check uniqueness in bytes representation, so lowerCaseAddr and mixedCaseAddr are the same, - // despite it differs in string representation - lowerCaseAddr := common.HexToAddress("0xab00000000000000000000000000000000000000") - mixedCaseAddr := common.HexToAddress("0xAb00000000000000000000000000000000000000") - - testCases := []struct { - name string - addrs []common.Address - unique bool - }{ - { - name: "success: addresses are unique", - addrs: []common.Address{addr1, addr2}, - unique: true, - }, - { - name: "failure: addresses are not unique", - addrs: []common.Address{addr1, addr1}, - unique: false, - }, - { - name: "failure: addresses are not unique in bytes representation", - addrs: []common.Address{lowerCaseAddr, mixedCaseAddr}, - unique: false, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - err := checkIfUniqueInBytesRepr(tc.addrs) - - if tc.unique { - require.NoError(t, err, tc.name) - } else { - require.Error(t, err, tc.name) - } - }) - } -}