diff --git a/adapters/database/service.go b/adapters/database/service.go index 5ca716c..5e11472 100644 --- a/adapters/database/service.go +++ b/adapters/database/service.go @@ -90,7 +90,7 @@ func (s *Service) GetActiveMeasurements(ctx context.Context) ([]domain.Measureme // RegisterCredentialsForBuilder registers new credentials for a builder, deprecating all previous credentials // It uses hash and attestation_type to fetch the corresponding measurement_id via a subquery. -func (s *Service) RegisterCredentialsForBuilder(ctx context.Context, builderName, service, tlsCert string, ecdsaPubKey []byte, measurementName, attestationType string) error { +func (s *Service) RegisterCredentialsForBuilder(ctx context.Context, builderName, service, tlsCert string, ecdsaPubKey []byte, measurementName, attestationType, region string) error { // Start a transaction tx, err := s.DB.BeginTx(ctx, nil) if err != nil { @@ -118,11 +118,12 @@ func (s *Service) RegisterCredentialsForBuilder(ctx context.Context, builderName _, err = tx.Exec(` INSERT INTO service_credential_registrations - (builder_name, service, tls_cert, ecdsa_pubkey, is_active, measurement_id) + (builder_name, service, tls_cert, ecdsa_pubkey, is_active, measurement_id, region) VALUES ($1, $2, $3, $4, true, - (SELECT id FROM measurements_whitelist WHERE name = $5 AND attestation_type = $6) + (SELECT id FROM measurements_whitelist WHERE name = $5 AND attestation_type = $6), + $7 ) - `, builderName, service, nullableTLSCert, ecdsaPubKey, measurementName, attestationType) + `, builderName, service, nullableTLSCert, ecdsaPubKey, measurementName, attestationType, region) if err != nil { return fmt.Errorf("failed to insert credentials for builder %s: %w", builderName, err) } @@ -156,7 +157,8 @@ func (s *Service) GetActiveBuildersWithServiceCredentials(ctx context.Context, n b.dns_name, scr.service, scr.tls_cert, - scr.ecdsa_pubkey + scr.ecdsa_pubkey, + scr.region FROM builders b LEFT JOIN @@ -180,8 +182,9 @@ func (s *Service) GetActiveBuildersWithServiceCredentials(ctx context.Context, n var tlsCert sql.NullString var dnsName sql.NullString var ecdsaPubKey []byte + var region sql.NullString - err := rows.Scan(&builderName, &ipAddress, &dnsName, &service, &tlsCert, &ecdsaPubKey) + err := rows.Scan(&builderName, &ipAddress, &dnsName, &service, &tlsCert, &ecdsaPubKey, ®ion) if err != nil { return nil, err } @@ -201,6 +204,7 @@ func (s *Service) GetActiveBuildersWithServiceCredentials(ctx context.Context, n Service: service.String, TLSCert: tlsCert, ECDSAPubKey: ecdsaPubKey, + Region: region.String, }) } } diff --git a/adapters/database/types.go b/adapters/database/types.go index 5d936fb..3aacf7d 100644 --- a/adapters/database/types.go +++ b/adapters/database/types.go @@ -84,6 +84,7 @@ type ServiceCredential struct { Service string TLSCert sql.NullString ECDSAPubKey []byte + Region string } func toDomainBuilderWithCredentials(builder BuilderWithCredentials) (*domain.BuilderWithServices, error) { @@ -104,6 +105,7 @@ func toDomainBuilderWithCredentials(builder BuilderWithCredentials) (*domain.Bui TLSCert: cred.TLSCert.String, ECDSAPubKey: domain.Bytes2Address(cred.ECDSAPubKey), Service: cred.Service, + Region: cred.Region, }) } return &s, nil diff --git a/application/service.go b/application/service.go index 02f4734..2972171 100644 --- a/application/service.go +++ b/application/service.go @@ -16,7 +16,7 @@ type BuilderDataAccessor interface { GetActiveMeasurementsByType(ctx context.Context, attestationType string) ([]domain.Measurement, error) GetBuilderByIP(ip net.IP) (*domain.Builder, error) GetActiveConfigForBuilder(ctx context.Context, builderName string) (json.RawMessage, error) - RegisterCredentialsForBuilder(ctx context.Context, builderName, service, tlsCert string, ecdsaPubKey []byte, measurementName, attestationType string) error + RegisterCredentialsForBuilder(ctx context.Context, builderName, service, tlsCert string, ecdsaPubKey []byte, measurementName, attestationType, region string) error LogEvent(ctx context.Context, eventName, builderName, name string) error } @@ -47,8 +47,8 @@ func (b *BuilderHub) LogEvent(ctx context.Context, eventName, builderName, name return b.dataAccessor.LogEvent(ctx, eventName, builderName, name) } -func (b *BuilderHub) RegisterCredentialsForBuilder(ctx context.Context, builderName, service, tlsCert string, ecdsaPubKey []byte, measurementName, attestationType string) error { - return b.dataAccessor.RegisterCredentialsForBuilder(ctx, builderName, service, tlsCert, ecdsaPubKey, measurementName, attestationType) +func (b *BuilderHub) RegisterCredentialsForBuilder(ctx context.Context, builderName, service, tlsCert string, ecdsaPubKey []byte, measurementName, attestationType, region string) error { + return b.dataAccessor.RegisterCredentialsForBuilder(ctx, builderName, service, tlsCert, ecdsaPubKey, measurementName, attestationType, region) } func (b *BuilderHub) GetConfigWithSecrets(ctx context.Context, builderName string) ([]byte, error) { diff --git a/domain/types.go b/domain/types.go index bfe8bbb..8970623 100644 --- a/domain/types.go +++ b/domain/types.go @@ -68,6 +68,7 @@ type BuilderServices struct { TLSCert string ECDSAPubKey *common.Address Service string + Region string } func Bytes2Address(b []byte) *common.Address { diff --git a/httpserver/e2e_test.go b/httpserver/e2e_test.go index 6afd40f..541c1ef 100644 --- a/httpserver/e2e_test.go +++ b/httpserver/e2e_test.go @@ -208,6 +208,7 @@ func TestAuthInteractionFlow(t *testing.T) { addr := common.HexToAddress("0x1234567890123456789012345678901234567890") sc := ports.ServiceCred{ ECDSAPubkey: &addr, + Region: "us-east-1", } status, _ := execRequestAuth(t, s.GetRouter(), http.MethodPost, "/api/l1-builder/v1/register_credentials/rbuilder", sc, nil, measurement.AttestationType, map[string]string{"8": "0000000000000000000000000000000000000000000000000000000000000000", "11": "efa43e0beff151b0f251c4abf48152382b1452b4414dbd737b4127de05ca31f7"}, "127.0.0.1") require.Equal(t, http.StatusOK, status) @@ -223,6 +224,7 @@ func TestAuthInteractionFlow(t *testing.T) { require.Equal(t, builderName+".builder.net", resp[0].DNSName) require.Equal(t, "", resp[0].ServiceCreds["rbuilder"].TLSCert) require.Equal(t, "0x1234567890123456789012345678901234567890", resp[0].ServiceCreds["rbuilder"].ECDSAPubkey.String()) + require.Equal(t, "us-east-1", resp[0].ServiceCreds["rbuilder"].Region) }) } diff --git a/ports/http_handler.go b/ports/http_handler.go index 29a0e4b..19ad7a9 100644 --- a/ports/http_handler.go +++ b/ports/http_handler.go @@ -20,7 +20,7 @@ type BuilderHubService interface { GetActiveBuilders(ctx context.Context, network string) ([]domain.BuilderWithServices, error) VerifyIPAndMeasurements(ctx context.Context, ip net.IP, measurement map[string]string, attestationType string) (*domain.Builder, string, error) GetConfigWithSecrets(ctx context.Context, builderName string) ([]byte, error) - RegisterCredentialsForBuilder(ctx context.Context, builderName, service, tlsCert string, ecdsaPubKey []byte, measurementName, attestationType string) error + RegisterCredentialsForBuilder(ctx context.Context, builderName, service, tlsCert string, ecdsaPubKey []byte, measurementName, attestationType, region string) error LogEvent(ctx context.Context, eventName, builderName, name string) error } type BuilderHubHandler struct { @@ -279,7 +279,7 @@ func (bhs *BuilderHubHandler) RegisterCredentials(w http.ResponseWriter, r *http ecdsaPubkey = sc.ECDSAPubkey.Bytes() } - err = bhs.builderHubService.RegisterCredentialsForBuilder(r.Context(), builder.Name, service, tlsCert, ecdsaPubkey, measurementName, authData.AttestationType) + err = bhs.builderHubService.RegisterCredentialsForBuilder(r.Context(), builder.Name, service, tlsCert, ecdsaPubkey, measurementName, authData.AttestationType, sc.Region) if err != nil { bhs.log.Error("Failed to register credentials", "err", err) w.WriteHeader(http.StatusInternalServerError) diff --git a/ports/types.go b/ports/types.go index 1d681e1..fff3ac6 100644 --- a/ports/types.go +++ b/ports/types.go @@ -31,6 +31,7 @@ type BuilderWithServiceCreds struct { type ServiceCred struct { TLSCert string `json:"tls_cert,omitempty"` ECDSAPubkey *common.Address `json:"ecdsa_pubkey_address,omitempty"` + Region string `json:"region,omitempty"` } // MarshalJSON is a custom json marshaller. Unfortunately, there seems to be no way to inline map[string]Service when marshalling @@ -110,6 +111,7 @@ func fromDomainBuilderWithServices(builder domain.BuilderWithServices) BuilderWi b.ServiceCreds[v.Service] = ServiceCred{ TLSCert: v.TLSCert, ECDSAPubkey: v.ECDSAPubKey, + Region: v.Region, } } diff --git a/ports/types_test.go b/ports/types_test.go index 640a5b9..048b867 100644 --- a/ports/types_test.go +++ b/ports/types_test.go @@ -35,6 +35,24 @@ func TestServiceCredsNil(t *testing.T) { } } +func TestUnmarshalBuildersWithRegion(t *testing.T) { + val := []byte(`[{"ip":"127.0.0.1","name":"test_builder_1","rbuilder":{"tls_cert":"test-cert","ecdsa_pubkey_address":"0x1234567890123456789012345678901234567890","region":"us-east-1"}}]`) + var builders []BuilderWithServiceCreds + err := json.Unmarshal(val, &builders) + if err != nil { + t.Fatalf("Failed to unmarshal builders: %v", err) + } + if len(builders) != 1 { + t.Fatal("Expected 1 builder") + } + if builders[0].ServiceCreds["rbuilder"].Region != "us-east-1" { + t.Errorf("Expected region us-east-1, got %s", builders[0].ServiceCreds["rbuilder"].Region) + } + if builders[0].ServiceCreds["rbuilder"].TLSCert != "test-cert" { + t.Error("Failed to unmarshal TLS cert") + } +} + func TestUnmarshalBuilders(t *testing.T) { val := []byte(`[{"ip":"127.0.0.1","name":"test_builder_1","rbuilder":{"tls_cert":"test-cert-no-validation","ecdsa_pubkey_address":"0x1234567890123456789012345678901234567890"}}]`) var builders []BuilderWithServiceCreds diff --git a/schema/004_region.sql b/schema/004_region.sql new file mode 100644 index 0000000..4e8384b --- /dev/null +++ b/schema/004_region.sql @@ -0,0 +1 @@ +ALTER TABLE service_credential_registrations ADD COLUMN region TEXT NOT NULL DEFAULT ''; diff --git a/scripts/ci/e2e-test.hurl b/scripts/ci/e2e-test.hurl index 6c1a50c..3d3b26b 100644 --- a/scripts/ci/e2e-test.hurl +++ b/scripts/ci/e2e-test.hurl @@ -100,7 +100,8 @@ HTTP 200 POST http://localhost:8888/api/l1-builder/v1/register_credentials/orderflow_proxy { "ecdsa_pubkey_address": "0x321f3426eEc20DE1910af1CD595c4DD83BEA0BA5", - "tls_cert": "abcdefghijklmnopqrstuvwxyz" + "tls_cert": "abcdefghijklmnopqrstuvwxyz", + "region": "europe" } HTTP 200 @@ -125,6 +126,7 @@ HTTP 200 [Asserts] jsonpath "$.[0].orderflow_proxy.tls_cert" == "abcdefghijklmnopqrstuvwxyz" jsonpath "$.[0].orderflow_proxy.ecdsa_pubkey_address" == "0x321f3426eec20de1910af1cd595c4dd83bea0ba5" +jsonpath "$.[0].orderflow_proxy.region" == "europe" jsonpath "$.[0].rbuilder.ecdsa_pubkey_address" == "0x321f3426eec20de1910af1cd595c4dd83bea0ba5" jsonpath "$.[0].instance.tls_cert" == "1234567890" jsonpath "$.[0].foobar123.tls_cert" == "1234567890"