44 "bytes"
55 "context"
66 "fmt"
7+ "net/url"
78 "sort"
9+ "strings"
810 "time"
911
1012 v1 "github.com/attestantio/go-eth2-client/api/v1"
@@ -21,6 +23,7 @@ import (
2123 execindexer "github.com/ethpandaops/dora/indexer/execution"
2224 "github.com/ethpandaops/dora/indexer/mevrelay"
2325 "github.com/ethpandaops/dora/indexer/snooper"
26+ "github.com/ethpandaops/dora/types"
2427 "github.com/ethpandaops/dora/utils"
2528 "github.com/sirupsen/logrus"
2629)
@@ -70,6 +73,67 @@ func InitChainService(ctx context.Context, logger logrus.FieldLogger) {
7073 }
7174}
7275
76+ // applyAuthGroupToEndpoint applies authGroup settings to an endpoint configuration
77+ func applyAuthGroupToEndpoint (endpoint * types.EndpointConfig ) (* types.EndpointConfig , error ) {
78+ if endpoint .AuthGroup == "" {
79+ return endpoint , nil
80+ }
81+
82+ authGroup , exists := utils .Config .AuthGroups [endpoint .AuthGroup ]
83+ if ! exists {
84+ return nil , fmt .Errorf ("authGroup '%s' not found" , endpoint .AuthGroup )
85+ }
86+
87+ // Create a copy of the endpoint to avoid modifying the original
88+ endpointCopy := * endpoint
89+
90+ // Apply credentials to URLs if provided
91+ if authGroup .Credentials != nil && (authGroup .Credentials .Username != "" || authGroup .Credentials .Password != "" ) {
92+ // Apply to main URL
93+ urlObj , err := url .Parse (endpointCopy .Url )
94+ if err != nil {
95+ return nil , fmt .Errorf ("failed to parse URL: %v" , err )
96+ }
97+
98+ if authGroup .Credentials .Username != "" && authGroup .Credentials .Password != "" {
99+ urlObj .User = url .UserPassword (authGroup .Credentials .Username , authGroup .Credentials .Password )
100+ } else if authGroup .Credentials .Username != "" {
101+ urlObj .User = url .User (authGroup .Credentials .Username )
102+ } else if authGroup .Credentials .Password != "" {
103+ credParts := strings .SplitN (authGroup .Credentials .Password , ":" , 2 )
104+ if len (credParts ) == 2 {
105+ urlObj .User = url .UserPassword (credParts [0 ], credParts [1 ])
106+ }
107+ }
108+ endpointCopy .Url = urlObj .String ()
109+
110+ // Apply to snooper URL if present
111+ if endpointCopy .EngineSnooperUrl != "" {
112+ snooperUrlObj , err := url .Parse (endpointCopy .EngineSnooperUrl )
113+ if err != nil {
114+ return nil , fmt .Errorf ("failed to parse snooper URL: %v" , err )
115+ }
116+
117+ snooperUrlObj .User = url .UserPassword (authGroup .Credentials .Username , authGroup .Credentials .Password )
118+ endpointCopy .EngineSnooperUrl = snooperUrlObj .String ()
119+ }
120+ }
121+
122+ // Merge headers (endpoint headers take precedence)
123+ if len (authGroup .Headers ) > 0 {
124+ if endpointCopy .Headers == nil {
125+ endpointCopy .Headers = make (map [string ]string )
126+ }
127+ for key , value := range authGroup .Headers {
128+ if _ , exists := endpointCopy .Headers [key ]; ! exists {
129+ endpointCopy .Headers [key ] = value
130+ }
131+ }
132+ }
133+
134+ return & endpointCopy , nil
135+ }
136+
73137// StartService is used to start the beaconchain service
74138func (cs * ChainService ) StartService () error {
75139 if cs .started {
@@ -81,30 +145,37 @@ func (cs *ChainService) StartService() error {
81145
82146 // add consensus clients
83147 for index , endpoint := range utils .Config .BeaconApi .Endpoints {
148+ // Apply authGroup settings if configured
149+ processedEndpoint , err := applyAuthGroupToEndpoint (& endpoint )
150+ if err != nil {
151+ cs .logger .Errorf ("could not apply authGroup to beacon client '%v': %v" , endpoint .Name , err )
152+ continue
153+ }
154+
84155 endpointConfig := & consensus.ClientConfig {
85- URL : endpoint .Url ,
86- Name : endpoint .Name ,
87- Headers : endpoint .Headers ,
156+ URL : processedEndpoint .Url ,
157+ Name : processedEndpoint .Name ,
158+ Headers : processedEndpoint .Headers ,
88159 DisableSSZ : utils .Config .KillSwitch .DisableSSZRequests ,
89160 }
90161
91- if endpoint .Ssh != nil {
162+ if processedEndpoint .Ssh != nil {
92163 endpointConfig .SshConfig = & sshtunnel.SshConfig {
93- Host : endpoint .Ssh .Host ,
94- Port : endpoint .Ssh .Port ,
95- User : endpoint .Ssh .User ,
96- Password : endpoint .Ssh .Password ,
97- Keyfile : endpoint .Ssh .Keyfile ,
164+ Host : processedEndpoint .Ssh .Host ,
165+ Port : processedEndpoint .Ssh .Port ,
166+ User : processedEndpoint .Ssh .User ,
167+ Password : processedEndpoint .Ssh .Password ,
168+ Keyfile : processedEndpoint .Ssh .Keyfile ,
98169 }
99170 }
100171
101172 client , err := cs .consensusPool .AddEndpoint (endpointConfig )
102173 if err != nil {
103- cs .logger .Errorf ("could not add beacon client '%v' to pool: %v" , endpoint .Name , err )
174+ cs .logger .Errorf ("could not add beacon client '%v' to pool: %v" , processedEndpoint .Name , err )
104175 continue
105176 }
106177
107- cs .beaconIndexer .AddClient (uint16 (index ), client , endpoint .Priority , endpoint .Archive , endpoint .SkipValidators )
178+ cs .beaconIndexer .AddClient (uint16 (index ), client , processedEndpoint .Priority , processedEndpoint .Archive , processedEndpoint .SkipValidators )
108179 }
109180
110181 if len (cs .consensusPool .GetAllEndpoints ()) == 0 {
@@ -113,34 +184,41 @@ func (cs *ChainService) StartService() error {
113184
114185 // add execution clients
115186 for _ , endpoint := range utils .Config .ExecutionApi .Endpoints {
187+ // Apply authGroup settings if configured
188+ processedEndpoint , err := applyAuthGroupToEndpoint (& endpoint )
189+ if err != nil {
190+ cs .logger .Errorf ("could not apply authGroup to execution client '%v': %v" , endpoint .Name , err )
191+ continue
192+ }
193+
116194 endpointConfig := & execution.ClientConfig {
117- URL : endpoint .Url ,
118- Name : endpoint .Name ,
119- Headers : endpoint .Headers ,
195+ URL : processedEndpoint .Url ,
196+ Name : processedEndpoint .Name ,
197+ Headers : processedEndpoint .Headers ,
120198 }
121199
122- if endpoint .Ssh != nil {
200+ if processedEndpoint .Ssh != nil {
123201 endpointConfig .SshConfig = & sshtunnel.SshConfig {
124- Host : endpoint .Ssh .Host ,
125- Port : endpoint .Ssh .Port ,
126- User : endpoint .Ssh .User ,
127- Password : endpoint .Ssh .Password ,
128- Keyfile : endpoint .Ssh .Keyfile ,
202+ Host : processedEndpoint .Ssh .Host ,
203+ Port : processedEndpoint .Ssh .Port ,
204+ User : processedEndpoint .Ssh .User ,
205+ Password : processedEndpoint .Ssh .Password ,
206+ Keyfile : processedEndpoint .Ssh .Keyfile ,
129207 }
130208 }
131209
132210 client , err := cs .executionPool .AddEndpoint (endpointConfig )
133211 if err != nil {
134- cs .logger .Errorf ("could not add execution client '%v' to pool: %v" , endpoint .Name , err )
212+ cs .logger .Errorf ("could not add execution client '%v' to pool: %v" , processedEndpoint .Name , err )
135213 continue
136214 }
137215
138- executionIndexerCtx .AddClientInfo (client , endpoint .Priority , endpoint .Archive )
216+ executionIndexerCtx .AddClientInfo (client , processedEndpoint .Priority , processedEndpoint .Archive )
139217
140218 // Add snooper client if configured
141- if endpoint .EngineSnooperUrl != "" {
142- if err := cs .snooperManager .AddClient (client , endpoint .EngineSnooperUrl ); err != nil {
143- cs .logger .WithError (err ).Errorf ("could not add snooper client for '%v'" , endpoint .Name )
219+ if processedEndpoint .EngineSnooperUrl != "" {
220+ if err := cs .snooperManager .AddClient (client , processedEndpoint .EngineSnooperUrl ); err != nil {
221+ cs .logger .WithError (err ).Errorf ("could not add snooper client for '%v'" , processedEndpoint .Name )
144222 }
145223 }
146224 }
0 commit comments