Repository: smartcontractkit/chainlink-solana
Pull request #1133: Add validation of URL in Node config
Author: login: prashantkumar1982
Created: 2025-03-17T21:00:59Z | Merged: 2025-03-18T02:14:33Z



Diff:
diff --git a/pkg/solana/config/config.go b/pkg/solana/config/config.go
index 676805e29..dd042cc57 100644
--- a/pkg/solana/config/config.go
+++ b/pkg/solana/config/config.go
@@ -166,8 +166,10 @@ func (n *Node) ValidateConfig() (err error) {
 	}
 	if n.URL == nil {
 		err = errors.Join(err, config.ErrMissing{Name: "URL", Msg: "required for all nodes"})
+	} else if n.URL.String() == "" {
+		err = errors.Join(err, config.ErrEmpty{Name: "URL", Msg: "required for all nodes"})
 	}
-	return
+	return err
 }
 
 func ptr[T any](t T) *T {
diff --git a/pkg/solana/config/config_test.go b/pkg/solana/config/config_test.go
new file mode 100644
index 000000000..c1c152187
--- /dev/null
+++ b/pkg/solana/config/config_test.go
@@ -0,0 +1,61 @@
+package config
+
+import (
+	"testing"
+
+	"github.com/smartcontractkit/chainlink-common/pkg/config"
+	"github.com/stretchr/testify/require"
+)
+
+func TestValidateConfig(t *testing.T) {
+	t.Parallel()
+
+	t.Run("Null Node name", func(t *testing.T) {
+		t.Parallel()
+		url := config.MustParseURL("http://url.com")
+		node := Node{
+			Name: nil,
+			URL:  url,
+		}
+		require.ErrorIs(t, node.ValidateConfig(), config.ErrMissing{Name: "Name", Msg: "required for all nodes"})
+	})
+	t.Run("Empty Node name", func(t *testing.T) {
+		t.Parallel()
+		nodeName := ""
+		url := config.MustParseURL("http://url.com")
+		node := Node{
+			Name: &nodeName,
+			URL:  url,
+		}
+		require.ErrorIs(t, node.ValidateConfig(), config.ErrEmpty{Name: "Name", Msg: "required for all nodes"})
+	})
+	t.Run("Null Node URL", func(t *testing.T) {
+		t.Parallel()
+		nodeName := "node"
+		node := Node{
+			Name: &nodeName,
+			URL:  nil,
+		}
+		require.ErrorIs(t, node.ValidateConfig(), config.ErrMissing{Name: "URL", Msg: "required for all nodes"})
+	})
+	t.Run("Empty Node URL", func(t *testing.T) {
+		t.Parallel()
+		nodeName := "node"
+		url := config.MustParseURL("")
+		node := Node{
+			Name: &nodeName,
+			URL:  url,
+		}
+		require.ErrorIs(t, node.ValidateConfig(), config.ErrEmpty{Name: "URL", Msg: "required for all nodes"})
+	})
+	t.Run("Valid config", func(t *testing.T) {
+		t.Parallel()
+		nodeName := "node"
+		url := config.MustParseURL("http://url.com")
+		node := Node{
+			Name: &nodeName,
+			URL:  url,
+		}
+		require.NoError(t, node.ValidateConfig())
+	})
+}


Reviews:
user: login: amit-momin
state: DISMISSED
author_association: COLLABORATOR
submitted_at: 2025-03-17T21:06:33Z
user: login: poopoothegorilla
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T21:30:47Z
user: login: poopoothegorilla
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T21:33:08Z
user: login: amit-momin
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T21:38:38Z
user: login: huangzhen1997
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T21:52:31Z
user: login: prashantkumar1982
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T21:55:45Z
user: login: poopoothegorilla
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T21:57:28Z
user: login: huangzhen1997
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T21:58:58Z
user: login: silaslenihan
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T21:59:09Z
user: login: amit-momin
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-17T22:02:42Z
user: login: chris-de-leon-cll
state: APPROVED
author_association: NONE
submitted_at: 2025-03-18T02:14:26Z

Review comments:
diff_hunk: @@ -166,8 +166,10 @@ func (n *Node) ValidateConfig() (err error) {
 	}
 	if n.URL == nil {
 		err = errors.Join(err, config.ErrMissing{Name: "URL", Msg: "required for all nodes"})
+	} else if n.URL.String() == "" {
path: pkg/solana/config/config.go
user: login: poopoothegorilla
body: nit: any reason for not doing `if n.URL == nil || n.URL.String() == "" {`


created_at: 2025-03-17T21:30:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -166,8 +166,10 @@ func (n *Node) ValidateConfig() (err error) {
 	}
 	if n.URL == nil {
 		err = errors.Join(err, config.ErrMissing{Name: "URL", Msg: "required for all nodes"})
+	} else if n.URL.String() == "" {
path: pkg/solana/config/config.go
user: login: amit-momin
body: Oh ya good catch, think we want separate conditions because we should use `ErrEmpty` instead of `ErrMissing ` when `n.URL.String() == ""`
created_at: 2025-03-17T21:38:38Z
author_association: COLLABORATOR
diff_hunk: @@ -166,8 +166,10 @@ func (n *Node) ValidateConfig() (err error) {
 	}
 	if n.URL == nil {
 		err = errors.Join(err, config.ErrMissing{Name: "URL", Msg: "required for all nodes"})
+	} else if n.URL.String() == "" {
+		err = errors.Join(err, config.ErrMissing{Name: "URL", Msg: "required for all nodes"})
path: pkg/solana/config/config.go
user: login: huangzhen1997
body: As Amit suggested, should we use `config.ErrEmpty` instead of `config.ErrMissing` ?
created_at: 2025-03-17T21:52:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -166,8 +166,10 @@ func (n *Node) ValidateConfig() (err error) {
 	}
 	if n.URL == nil {
 		err = errors.Join(err, config.ErrMissing{Name: "URL", Msg: "required for all nodes"})
+	} else if n.URL.String() == "" {
path: pkg/solana/config/config.go
user: login: prashantkumar1982
body: Thanks, good catch.
Fixed, and updated tests too
created_at: 2025-03-17T21:55:44Z
author_association: CONTRIBUTOR

PR comments:
user: login: cl-sonarqube-production[bot]
created_at: 2025-03-17T22:11:37Z
body: ## [![Quality Gate passed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v104/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarqube.main.prod.cldev.sh/dashboard?id=smartcontractkit_chainlink-solana&pullRequest=1133) **Quality Gate passed**  
Issues  
[![](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v104/common/passed-16px.png '')](https://sonarqube.main.prod.cldev.sh/project/issues?id=smartcontractkit_chainlink-solana&pullRequest=1133&resolved=false) [0 New issues](https://sonarqube.main.prod.cldev.sh/project/issues?id=smartcontractkit_chainlink-solana&pullRequest=1133&resolved=false)  
[![](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v104/common/fixed-16px.png '')](https://sonarqube.main.prod.cldev.sh/project/issues?id=smartcontractkit_chainlink-solana&fixedInPullRequest=1133) [0 Fixed issues](https://sonarqube.main.prod.cldev.sh/project/issues?id=smartcontractkit_chainlink-solana&fixedInPullRequest=1133)  
[![](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v104/common/accepted-16px.png '')](https://sonarqube.main.prod.cldev.sh/project/issues?id=smartcontractkit_chainlink-solana&pullRequest=1133&issueStatuses=ACCEPTED) [0 Accepted issues](https://sonarqube.main.prod.cldev.sh/project/issues?id=smartcontractkit_chainlink-solana&pullRequest=1133&issueStatuses=ACCEPTED)

Measures  
[![](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v104/common/passed-16px.png '')](https://sonarqube.main.prod.cldev.sh/security_hotspots?id=smartcontractkit_chainlink-solana&pullRequest=1133) [0 Security Hotspots](https://sonarqube.main.prod.cldev.sh/security_hotspots?id=smartcontractkit_chainlink-solana&pullRequest=1133)  
[![](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v104/common/passed-16px.png '')](https://sonarqube.main.prod.cldev.sh/component_measures?id=smartcontractkit_chainlink-solana&pullRequest=1133&metric=new_coverage&view=list) [100.0% Coverage on New Code](https://sonarqube.main.prod.cldev.sh/component_measures?id=smartcontractkit_chainlink-solana&pullRequest=1133&metric=new_coverage&view=list)  
[![](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v104/common/passed-16px.png '')](https://sonarqube.main.prod.cldev.sh/component_measures?id=smartcontractkit_chainlink-solana&pullRequest=1133&metric=new_duplicated_lines_density&view=list) [0.0% Duplication on New Code](https://sonarqube.main.prod.cldev.sh/component_measures?id=smartcontractkit_chainlink-solana&pullRequest=1133&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube](https://sonarqube.main.prod.cldev.sh/dashboard?id=smartcontractkit_chainlink-solana&pullRequest=1133)


author_association: NONE