From 310fb0de342261bab2f55282dca2bf55ae45839e Mon Sep 17 00:00:00 2001 From: Patrick Pfeiffer <306324+guybrush@users.noreply.github.com> Date: Mon, 11 Nov 2024 12:18:20 +0100 Subject: [PATCH 1/4] ci: build and push docker-images for staging-2 --- .github/workflows/backend-publish-docker.yml | 1 + .github/workflows/frontend-publish-docker.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/backend-publish-docker.yml b/.github/workflows/backend-publish-docker.yml index adfb81822..f766263fc 100644 --- a/.github/workflows/backend-publish-docker.yml +++ b/.github/workflows/backend-publish-docker.yml @@ -10,6 +10,7 @@ on: branches: - main - staging + - staging-2 # Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. env: diff --git a/.github/workflows/frontend-publish-docker.yml b/.github/workflows/frontend-publish-docker.yml index 8c85468f9..b93c4b312 100644 --- a/.github/workflows/frontend-publish-docker.yml +++ b/.github/workflows/frontend-publish-docker.yml @@ -10,6 +10,7 @@ on: branches: - main - staging + - staging-2 # Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. env: From b02c5a1823a8fbcfe7dcedc6ae1459483884fc5e Mon Sep 17 00:00:00 2001 From: Lucca Dukic <109136188+LuccaBitfly@users.noreply.github.com> Date: Wed, 6 Nov 2024 15:12:01 +0100 Subject: [PATCH 2/4] refactor: rename search types and handlers file See: BEDS-934 --- backend/pkg/api/handlers/{search_handlers.go => search.go} | 0 backend/pkg/api/types/{search_types.go => search.go} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename backend/pkg/api/handlers/{search_handlers.go => search.go} (100%) rename backend/pkg/api/types/{search_types.go => search.go} (100%) diff --git a/backend/pkg/api/handlers/search_handlers.go b/backend/pkg/api/handlers/search.go similarity index 100% rename from backend/pkg/api/handlers/search_handlers.go rename to backend/pkg/api/handlers/search.go diff --git a/backend/pkg/api/types/search_types.go b/backend/pkg/api/types/search.go similarity index 100% rename from backend/pkg/api/types/search_types.go rename to backend/pkg/api/types/search.go From 867cad9135a138580f82bea64c17be6249fc8a25 Mon Sep 17 00:00:00 2001 From: Lucca Dukic <109136188+LuccaBitfly@users.noreply.github.com> Date: Wed, 6 Nov 2024 15:33:06 +0100 Subject: [PATCH 3/4] refactor: better search result types See: BEDS-934 --- backend/pkg/api/api_test.go | 15 ++- backend/pkg/api/data_access/dummy.go | 8 +- backend/pkg/api/data_access/search.go | 19 +-- backend/pkg/api/handlers/search.go | 171 ++++++++++---------------- backend/pkg/api/types/common.go | 10 -- backend/pkg/api/types/search.go | 38 +++--- frontend/types/api/common.ts | 8 -- frontend/types/api/search.ts | 35 ++++++ 8 files changed, 147 insertions(+), 157 deletions(-) create mode 100644 frontend/types/api/search.ts diff --git a/backend/pkg/api/api_test.go b/backend/pkg/api/api_test.go index 8d5423fa5..11a4c4e07 100644 --- a/backend/pkg/api/api_test.go +++ b/backend/pkg/api/api_test.go @@ -298,8 +298,9 @@ func TestInternalSearchHandler(t *testing.T) { }`)).Expect().Status(http.StatusOK).JSON().Decode(&resp) assert.NotEqual(t, 0, len(resp.Data), "response data should not be empty") - assert.NotNil(t, resp.Data[0].NumValue, "validator index should not be nil") - assert.Equal(t, uint64(5), *resp.Data[0].NumValue, "validator index should be 5") + validatorByIndex, ok := resp.Data[0].Value.(api_types.SearchValidator) + assert.True(t, ok, "response data should be of type SearchValidator") + assert.Equal(t, uint64(5), validatorByIndex.Index, "validator index should be 5") // search for validator by pubkey resp = api_types.InternalPostSearchResponse{} @@ -324,8 +325,9 @@ func TestInternalSearchHandler(t *testing.T) { }`)).Expect().Status(http.StatusOK).JSON().Decode(&resp) assert.NotEqual(t, 0, len(resp.Data), "response data should not be empty") - assert.NotNil(t, resp.Data[0].NumValue, "validator index should not be nil") - assert.Equal(t, uint64(5), *resp.Data[0].NumValue, "validator index should be 5") + validatorByPublicKey, ok := resp.Data[0].Value.(api_types.SearchValidator) + assert.True(t, ok, "response data should be of type SearchValidator") + assert.Equal(t, uint64(5), validatorByPublicKey.Index, "validator index should be 5") // search for validator by withdawal address resp = api_types.InternalPostSearchResponse{} @@ -349,8 +351,9 @@ func TestInternalSearchHandler(t *testing.T) { }`)).Expect().Status(http.StatusOK).JSON().Decode(&resp) assert.NotEqual(t, 0, len(resp.Data), "response data should not be empty") - assert.NotNil(t, resp.Data[0].NumValue, "validator index should not be nil") - assert.Greater(t, *resp.Data[0].NumValue, uint64(0), "returned number of validators should be greater than 0") + validatorsByWithdrawalAddress, ok := resp.Data[0].Value.(api_types.SearchValidatorsByWithdrwalCredential) + assert.True(t, ok, "response data should be of type SearchValidator") + assert.Greater(t, validatorsByWithdrawalAddress.Count, uint64(0), "returned number of validators should be greater than 0") } func TestPublicAndSharedDashboards(t *testing.T) { diff --git a/backend/pkg/api/data_access/dummy.go b/backend/pkg/api/data_access/dummy.go index ebb280b1e..84915194f 100644 --- a/backend/pkg/api/data_access/dummy.go +++ b/backend/pkg/api/data_access/dummy.go @@ -514,16 +514,16 @@ func (d *DummyService) GetSearchValidatorsByDepositAddress(ctx context.Context, return getDummyStruct[t.SearchValidatorsByDepositAddress](ctx) } -func (d *DummyService) GetSearchValidatorsByDepositEnsName(ctx context.Context, chainId uint64, ensName string) (*t.SearchValidatorsByDepositEnsName, error) { - return getDummyStruct[t.SearchValidatorsByDepositEnsName](ctx) +func (d *DummyService) GetSearchValidatorsByDepositEnsName(ctx context.Context, chainId uint64, ensName string) (*t.SearchValidatorsByDepositAddress, error) { + return getDummyStruct[t.SearchValidatorsByDepositAddress](ctx) } func (d *DummyService) GetSearchValidatorsByWithdrawalCredential(ctx context.Context, chainId uint64, credential []byte) (*t.SearchValidatorsByWithdrwalCredential, error) { return getDummyStruct[t.SearchValidatorsByWithdrwalCredential](ctx) } -func (d *DummyService) GetSearchValidatorsByWithdrawalEnsName(ctx context.Context, chainId uint64, ensName string) (*t.SearchValidatorsByWithrawalEnsName, error) { - return getDummyStruct[t.SearchValidatorsByWithrawalEnsName](ctx) +func (d *DummyService) GetSearchValidatorsByWithdrawalEnsName(ctx context.Context, chainId uint64, ensName string) (*t.SearchValidatorsByWithdrwalCredential, error) { + return getDummyStruct[t.SearchValidatorsByWithdrwalCredential](ctx) } func (d *DummyService) GetSearchValidatorsByGraffiti(ctx context.Context, chainId uint64, graffiti string) (*t.SearchValidatorsByGraffiti, error) { diff --git a/backend/pkg/api/data_access/search.go b/backend/pkg/api/data_access/search.go index 57221fbda..d177e0161 100644 --- a/backend/pkg/api/data_access/search.go +++ b/backend/pkg/api/data_access/search.go @@ -12,9 +12,9 @@ type SearchRepository interface { GetSearchValidatorByIndex(ctx context.Context, chainId, index uint64) (*t.SearchValidator, error) GetSearchValidatorByPublicKey(ctx context.Context, chainId uint64, publicKey []byte) (*t.SearchValidator, error) GetSearchValidatorsByDepositAddress(ctx context.Context, chainId uint64, address []byte) (*t.SearchValidatorsByDepositAddress, error) - GetSearchValidatorsByDepositEnsName(ctx context.Context, chainId uint64, ensName string) (*t.SearchValidatorsByDepositEnsName, error) + GetSearchValidatorsByDepositEnsName(ctx context.Context, chainId uint64, ensName string) (*t.SearchValidatorsByDepositAddress, error) GetSearchValidatorsByWithdrawalCredential(ctx context.Context, chainId uint64, credential []byte) (*t.SearchValidatorsByWithdrwalCredential, error) - GetSearchValidatorsByWithdrawalEnsName(ctx context.Context, chainId uint64, ensName string) (*t.SearchValidatorsByWithrawalEnsName, error) + GetSearchValidatorsByWithdrawalEnsName(ctx context.Context, chainId uint64, ensName string) (*t.SearchValidatorsByWithdrwalCredential, error) GetSearchValidatorsByGraffiti(ctx context.Context, chainId uint64, graffiti string) (*t.SearchValidatorsByGraffiti, error) } @@ -28,7 +28,7 @@ func (d *DataAccessService) GetSearchValidatorByIndex(ctx context.Context, chain if int(index) < len(validatorMapping.ValidatorPubkeys) { return &t.SearchValidator{ Index: index, - PublicKey: hexutil.MustDecode(validatorMapping.ValidatorPubkeys[index]), + PublicKey: validatorMapping.ValidatorPubkeys[index], }, nil } @@ -46,7 +46,7 @@ func (d *DataAccessService) GetSearchValidatorByPublicKey(ctx context.Context, c if index, found := validatorMapping.ValidatorIndices[b]; found { return &t.SearchValidator{ Index: index, - PublicKey: publicKey, + PublicKey: b, }, nil } @@ -56,9 +56,10 @@ func (d *DataAccessService) GetSearchValidatorByPublicKey(ctx context.Context, c func (d *DataAccessService) GetSearchValidatorsByDepositAddress(ctx context.Context, chainId uint64, address []byte) (*t.SearchValidatorsByDepositAddress, error) { // TODO: implement handling of chainid ret := &t.SearchValidatorsByDepositAddress{ - Address: address, + DepositAddress: hexutil.Encode(address), } - err := db.ReaderDb.GetContext(ctx, &ret.Count, "select count(validatorindex) from validators where pubkey in (select publickey from eth1_deposits where from_address = $1);", address) + err := db.ReaderDb.GetContext(ctx, &ret.Count, ` + select count(validatorindex) from validators where pubkey in (select publickey from eth1_deposits where from_address = $1);`, address) if err != nil { return nil, err } @@ -68,7 +69,7 @@ func (d *DataAccessService) GetSearchValidatorsByDepositAddress(ctx context.Cont return ret, nil } -func (d *DataAccessService) GetSearchValidatorsByDepositEnsName(ctx context.Context, chainId uint64, ensName string) (*t.SearchValidatorsByDepositEnsName, error) { +func (d *DataAccessService) GetSearchValidatorsByDepositEnsName(ctx context.Context, chainId uint64, ensName string) (*t.SearchValidatorsByDepositAddress, error) { // TODO: implement handling of chainid // TODO: finalize ens implementation first return nil, ErrNotFound @@ -77,7 +78,7 @@ func (d *DataAccessService) GetSearchValidatorsByDepositEnsName(ctx context.Cont func (d *DataAccessService) GetSearchValidatorsByWithdrawalCredential(ctx context.Context, chainId uint64, credential []byte) (*t.SearchValidatorsByWithdrwalCredential, error) { // TODO: implement handling of chainid ret := &t.SearchValidatorsByWithdrwalCredential{ - WithdrawalCredential: credential, + WithdrawalCredential: hexutil.Encode(credential), } err := db.ReaderDb.GetContext(ctx, &ret.Count, "select count(validatorindex) from validators where withdrawalcredentials = $1;", credential) if err != nil { @@ -89,7 +90,7 @@ func (d *DataAccessService) GetSearchValidatorsByWithdrawalCredential(ctx contex return ret, nil } -func (d *DataAccessService) GetSearchValidatorsByWithdrawalEnsName(ctx context.Context, chainId uint64, ensName string) (*t.SearchValidatorsByWithrawalEnsName, error) { +func (d *DataAccessService) GetSearchValidatorsByWithdrawalEnsName(ctx context.Context, chainId uint64, ensName string) (*t.SearchValidatorsByWithdrwalCredential, error) { // TODO: implement handling of chainid // TODO: finalize ens implementation first return nil, ErrNotFound diff --git a/backend/pkg/api/handlers/search.go b/backend/pkg/api/handlers/search.go index 531c0f898..e1a9f28c6 100644 --- a/backend/pkg/api/handlers/search.go +++ b/backend/pkg/api/handlers/search.go @@ -33,16 +33,48 @@ const ( ) // source of truth for all possible search types and their regex -var searchTypeToRegex = map[searchTypeKey]*regexp.Regexp{ - validatorByIndex: reInteger, - validatorByPublicKey: reValidatorPublicKey, - validatorList: reValidatorList, - validatorsByDepositAddress: reEthereumAddress, - validatorsByDepositEnsName: reEnsName, - validatorsByWithdrawalCredential: reWithdrawalCredential, - validatorsByWithdrawalAddress: reEthereumAddress, - validatorsByWithdrawalEns: reEnsName, - validatorsByGraffiti: reGraffiti, +var searchTypeMap = map[searchTypeKey]searchType{ + validatorByIndex: { + regex: reInteger, + responseType: "validator", + }, + validatorByPublicKey: { + regex: reValidatorPublicKey, + responseType: "validator", + }, + validatorList: { + regex: reValidatorList, + responseType: string(validatorList), + }, + validatorsByDepositAddress: { + regex: reEthereumAddress, + responseType: string(validatorsByDepositAddress), + }, + validatorsByDepositEnsName: { + regex: reEnsName, + responseType: string(validatorsByDepositAddress), + }, + validatorsByWithdrawalCredential: { + regex: reWithdrawalCredential, + responseType: string(validatorsByWithdrawalCredential), + }, + validatorsByWithdrawalAddress: { + regex: reEthereumAddress, + responseType: string(validatorsByWithdrawalCredential), + }, + validatorsByWithdrawalEns: { + regex: reEnsName, + responseType: string(validatorsByWithdrawalCredential), + }, + validatorsByGraffiti: { + regex: reGraffiti, + responseType: string(validatorsByGraffiti), + }, +} + +type searchType struct { + regex *regexp.Regexp + responseType string } // -------------------------------------- @@ -74,7 +106,7 @@ func (h *HandlerService) InternalPostSearch(w http.ResponseWriter, r *http.Reque // iterate over all combinations of search types and networks for _, searchType := range searchTypeSet { // check if input matches the regex for the search type - if !searchTypeToRegex[searchType].MatchString(req.Input) { + if !searchTypeMap[searchType].regex.MatchString(req.Input) { continue } for _, chainId := range chainIdSet { @@ -146,6 +178,17 @@ func (h *HandlerService) handleSearchType(ctx context.Context, input string, sea } } +func asSearchResult[In any](searchType searchTypeKey, chainId uint64, result *In, err error) (*types.SearchResult, error) { + if err != nil || result == nil { + return nil, err + } + return &types.SearchResult{ + Type: searchTypeMap[searchType].responseType, + ChainId: chainId, + Value: result, + }, nil +} + func (h *HandlerService) handleSearchValidatorByIndex(ctx context.Context, input string, chainId uint64) (*types.SearchResult, error) { index, err := strconv.ParseUint(input, 10, 64) if err != nil { @@ -153,16 +196,7 @@ func (h *HandlerService) handleSearchValidatorByIndex(ctx context.Context, input return nil, err } result, err := h.daService.GetSearchValidatorByIndex(ctx, chainId, index) - if err != nil { - return nil, err - } - - return &types.SearchResult{ - Type: string(validatorByIndex), - ChainId: chainId, - HashValue: "0x" + hex.EncodeToString(result.PublicKey), - NumValue: &result.Index, - }, nil + return asSearchResult(validatorByIndex, chainId, result, err) } func (h *HandlerService) handleSearchValidatorByPublicKey(ctx context.Context, input string, chainId uint64) (*types.SearchResult, error) { @@ -172,16 +206,7 @@ func (h *HandlerService) handleSearchValidatorByPublicKey(ctx context.Context, i return nil, err } result, err := h.daService.GetSearchValidatorByPublicKey(ctx, chainId, publicKey) - if err != nil { - return nil, err - } - - return &types.SearchResult{ - Type: string(validatorByPublicKey), - ChainId: chainId, - HashValue: "0x" + hex.EncodeToString(result.PublicKey), - NumValue: &result.Index, - }, nil + return asSearchResult(validatorByPublicKey, chainId, result, err) } func (h *HandlerService) handleSearchValidatorList(ctx context.Context, input string, chainId uint64) (*types.SearchResult, error) { @@ -192,18 +217,14 @@ func (h *HandlerService) handleSearchValidatorList(ctx context.Context, input st return nil, nil // return no error as to not disturb the other search types } validators, err := h.daService.GetValidatorsFromSlices(ctx, indices, pubkeys) - if err != nil { + if err != nil || validators == nil || len(validators) == 0 { return nil, err } - if len(validators) == 0 { - return nil, nil - } - var resultLength uint64 = uint64(len(validators)) return &types.SearchResult{ - Type: string(validatorList), - ChainId: chainId, - NumValue: &resultLength, + Type: searchTypeMap[validatorList].responseType, + ChainId: chainId, + Value: types.SearchValidatorList{Validators: validators}, }, nil } @@ -213,31 +234,12 @@ func (h *HandlerService) handleSearchValidatorsByDepositAddress(ctx context.Cont return nil, err } result, err := h.daService.GetSearchValidatorsByDepositAddress(ctx, chainId, address) - if err != nil { - return nil, err - } - - return &types.SearchResult{ - Type: string(validatorsByDepositAddress), - ChainId: chainId, - HashValue: "0x" + hex.EncodeToString(result.Address), - NumValue: &result.Count, - }, nil + return asSearchResult(validatorsByDepositAddress, chainId, result, err) } func (h *HandlerService) handleSearchValidatorsByDepositEnsName(ctx context.Context, input string, chainId uint64) (*types.SearchResult, error) { result, err := h.daService.GetSearchValidatorsByDepositEnsName(ctx, chainId, input) - if err != nil { - return nil, err - } - - return &types.SearchResult{ - Type: string(validatorsByDepositEnsName), - ChainId: chainId, - StrValue: result.EnsName, - HashValue: "0x" + hex.EncodeToString(result.Address), - NumValue: &result.Count, - }, nil + return asSearchResult(validatorsByDepositEnsName, chainId, result, err) } func (h *HandlerService) handleSearchValidatorsByWithdrawalCredential(ctx context.Context, input string, chainId uint64) (*types.SearchResult, error) { @@ -246,16 +248,7 @@ func (h *HandlerService) handleSearchValidatorsByWithdrawalCredential(ctx contex return nil, err } result, err := h.daService.GetSearchValidatorsByWithdrawalCredential(ctx, chainId, withdrawalCredential) - if err != nil { - return nil, err - } - - return &types.SearchResult{ - Type: string(validatorsByWithdrawalCredential), - ChainId: chainId, - HashValue: "0x" + hex.EncodeToString(result.WithdrawalCredential), - NumValue: &result.Count, - }, nil + return asSearchResult(validatorsByWithdrawalCredential, chainId, result, err) } func (h *HandlerService) handleSearchValidatorsByWithdrawalAddress(ctx context.Context, input string, chainId uint64) (*types.SearchResult, error) { @@ -265,45 +258,17 @@ func (h *HandlerService) handleSearchValidatorsByWithdrawalAddress(ctx context.C return nil, err } result, err := h.daService.GetSearchValidatorsByWithdrawalCredential(ctx, chainId, withdrawalCredential) - if err != nil { - return nil, err - } - - return &types.SearchResult{ - Type: string(validatorsByWithdrawalAddress), - ChainId: chainId, - HashValue: "0x" + hex.EncodeToString(result.WithdrawalCredential), - NumValue: &result.Count, - }, nil + return asSearchResult(validatorsByWithdrawalAddress, chainId, result, err) } func (h *HandlerService) handleSearchValidatorsByWithdrawalEnsName(ctx context.Context, input string, chainId uint64) (*types.SearchResult, error) { result, err := h.daService.GetSearchValidatorsByWithdrawalEnsName(ctx, chainId, input) - if err != nil { - return nil, err - } - - return &types.SearchResult{ - Type: string(validatorsByWithdrawalEns), - ChainId: chainId, - StrValue: result.EnsName, - HashValue: "0x" + hex.EncodeToString(result.Address), - NumValue: &result.Count, - }, nil + return asSearchResult(validatorsByWithdrawalEns, chainId, result, err) } func (h *HandlerService) handleSearchValidatorsByGraffiti(ctx context.Context, input string, chainId uint64) (*types.SearchResult, error) { result, err := h.daService.GetSearchValidatorsByGraffiti(ctx, chainId, input) - if err != nil { - return nil, err - } - - return &types.SearchResult{ - Type: string(validatorsByGraffiti), - ChainId: chainId, - StrValue: result.Graffiti, - NumValue: &result.Count, - }, nil + return asSearchResult(validatorsByGraffiti, chainId, result, err) } // -------------------------------------- @@ -336,14 +301,14 @@ func (v *validationError) checkSearchTypes(types []searchTypeKey) []searchTypeKe typeSet := map[searchTypeKey]struct{}{} // if the list is empty, query all types if len(types) == 0 { - for t := range searchTypeToRegex { + for t := range searchTypeMap { typeSet[t] = struct{}{} } return slices.Collect(maps.Keys(typeSet)) } // list not empty, check if types are valid for _, t := range types { - if _, typeExists := searchTypeToRegex[t]; !typeExists { + if _, typeExists := searchTypeMap[t]; !typeExists { v.add("types", fmt.Sprintf("invalid search type '%s'", t)) continue } diff --git a/backend/pkg/api/types/common.go b/backend/pkg/api/types/common.go index 047cadac6..e64c29cc1 100644 --- a/backend/pkg/api/types/common.go +++ b/backend/pkg/api/types/common.go @@ -113,16 +113,6 @@ type ChainConfig struct { // TODO: add more fields, depending on what frontend needs } -type SearchResult struct { - Type string `json:"type"` - ChainId uint64 `json:"chain_id"` - HashValue string `json:"hash_value,omitempty"` - StrValue string `json:"str_value,omitempty"` - NumValue *uint64 `json:"num_value,omitempty"` -} - -type InternalPostSearchResponse ApiDataResponse[[]SearchResult] - type VDBPublicId struct { PublicId string `json:"public_id"` DashboardId int `json:"-"` diff --git a/backend/pkg/api/types/search.go b/backend/pkg/api/types/search.go index c289d0e82..202b1607e 100644 --- a/backend/pkg/api/types/search.go +++ b/backend/pkg/api/types/search.go @@ -3,33 +3,37 @@ package types // search types to be used between the data access layer and the api layer, shouldn't be exported to typescript type SearchValidator struct { - Index uint64 - PublicKey []byte + Index uint64 `json:"index"` + PublicKey string `json:"public_key"` } -type SearchValidatorsByDepositEnsName struct { - EnsName string - Address []byte - Count uint64 +type SearchValidatorList struct { + Validators []uint64 `json:"validators"` } type SearchValidatorsByDepositAddress struct { - Address []byte - Count uint64 + EnsName string `json:"ens_name,omitempty"` + DepositAddress string `json:"deposit_address"` + Count uint64 `json:"count"` } type SearchValidatorsByWithdrwalCredential struct { - WithdrawalCredential []byte - Count uint64 + EnsName string `json:"ens_name,omitempty"` + WithdrawalCredential string `json:"withdrawal_credential"` + Count uint64 `json:"count"` } -type SearchValidatorsByWithrawalEnsName struct { - EnsName string - Address []byte - Count uint64 +type SearchValidatorsByGraffiti struct { + Graffiti string `json:"graffiti"` + Count uint64 `json:"count"` } -type SearchValidatorsByGraffiti struct { - Graffiti string - Count uint64 +type SearchResult struct { + Type string `json:"type"` + ChainId uint64 `json:"chain_id"` + Value interface{} `json:"value"` +} + +type InternalPostSearchResponse struct { + Data []SearchResult `json:"data" tstype:"({ type: 'validator'; chain_id: number; value: SearchValidator } | { type: 'validator_list'; chain_id: number; value: SearchValidatorList } | { type: 'validators_by_deposit_address'; chain_id: number; value: SearchValidatorsByDepositAddress } | { type: 'validators_by_withdrawal_credential'; chain_id: number; value: SearchValidatorsByWithdrwalCredential } | { type: 'validators_by_graffiti'; chain_id: number; value: SearchValidatorsByGraffiti })[]"` } diff --git a/frontend/types/api/common.ts b/frontend/types/api/common.ts index 992f10f01..64c633d22 100644 --- a/frontend/types/api/common.ts +++ b/frontend/types/api/common.ts @@ -92,14 +92,6 @@ export interface ChainConfig { chain_id: number /* uint64 */; name: string; } -export interface SearchResult { - type: string; - chain_id: number /* uint64 */; - hash_value?: string; - str_value?: string; - num_value?: number /* uint64 */; -} -export type InternalPostSearchResponse = ApiDataResponse; export interface VDBPublicId { public_id: string; name?: string; diff --git a/frontend/types/api/search.ts b/frontend/types/api/search.ts new file mode 100644 index 000000000..e5f2eb870 --- /dev/null +++ b/frontend/types/api/search.ts @@ -0,0 +1,35 @@ +// Code generated by tygo. DO NOT EDIT. +/* eslint-disable */ + +////////// +// source: search.go + +export interface SearchValidator { + index: number /* uint64 */; + public_key: string; +} +export interface SearchValidatorList { + validators: number /* uint64 */[]; +} +export interface SearchValidatorsByDepositAddress { + ens_name?: string; + deposit_address: string; + count: number /* uint64 */; +} +export interface SearchValidatorsByWithdrwalCredential { + ens_name?: string; + withdrawal_credential: string; + count: number /* uint64 */; +} +export interface SearchValidatorsByGraffiti { + graffiti: string; + count: number /* uint64 */; +} +export interface SearchResult { + type: string; + chain_id: number /* uint64 */; + value: any; +} +export interface InternalPostSearchResponse { + data: ({ type: 'validator'; chain_id: number; value: SearchValidator } | { type: 'validator_list'; chain_id: number; value: SearchValidatorList } | { type: 'validators_by_deposit_address'; chain_id: number; value: SearchValidatorsByDepositAddress } | { type: 'validators_by_withdrawal_credential'; chain_id: number; value: SearchValidatorsByWithdrwalCredential } | { type: 'validators_by_graffiti'; chain_id: number; value: SearchValidatorsByGraffiti })[]; +} From 38e89d21dbfe69a2cdc175edcb76d4351e851ca2 Mon Sep 17 00:00:00 2001 From: Lucca Dukic <109136188+LuccaBitfly@users.noreply.github.com> Date: Fri, 15 Nov 2024 14:31:47 +0100 Subject: [PATCH 4/4] refactor: rename withdrawal_address to withdrawal_credential - Renames payload parameter when adding validators by withdrawal credential, as this also supports non-addresses. See: BEDS-934 --- backend/pkg/api/data_access/dummy.go | 2 +- backend/pkg/api/data_access/vdb.go | 2 +- backend/pkg/api/data_access/vdb_management.go | 4 ++-- backend/pkg/api/handlers/public.go | 24 +++++++++---------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/backend/pkg/api/data_access/dummy.go b/backend/pkg/api/data_access/dummy.go index 84915194f..b336e27da 100644 --- a/backend/pkg/api/data_access/dummy.go +++ b/backend/pkg/api/data_access/dummy.go @@ -274,7 +274,7 @@ func (d *DummyService) AddValidatorDashboardValidatorsByDepositAddress(ctx conte return getDummyData[[]t.VDBPostValidatorsData](ctx) } -func (d *DummyService) AddValidatorDashboardValidatorsByWithdrawalAddress(ctx context.Context, dashboardId t.VDBIdPrimary, groupId uint64, address string, limit uint64) ([]t.VDBPostValidatorsData, error) { +func (d *DummyService) AddValidatorDashboardValidatorsByWithdrawalCredential(ctx context.Context, dashboardId t.VDBIdPrimary, groupId uint64, address string, limit uint64) ([]t.VDBPostValidatorsData, error) { return getDummyData[[]t.VDBPostValidatorsData](ctx) } diff --git a/backend/pkg/api/data_access/vdb.go b/backend/pkg/api/data_access/vdb.go index b32aebc8d..8eadc6352 100644 --- a/backend/pkg/api/data_access/vdb.go +++ b/backend/pkg/api/data_access/vdb.go @@ -31,7 +31,7 @@ type ValidatorDashboardRepository interface { AddValidatorDashboardValidators(ctx context.Context, dashboardId t.VDBIdPrimary, groupId uint64, validators []t.VDBValidator) ([]t.VDBPostValidatorsData, error) AddValidatorDashboardValidatorsByDepositAddress(ctx context.Context, dashboardId t.VDBIdPrimary, groupId uint64, address string, limit uint64) ([]t.VDBPostValidatorsData, error) - AddValidatorDashboardValidatorsByWithdrawalAddress(ctx context.Context, dashboardId t.VDBIdPrimary, groupId uint64, address string, limit uint64) ([]t.VDBPostValidatorsData, error) + AddValidatorDashboardValidatorsByWithdrawalCredential(ctx context.Context, dashboardId t.VDBIdPrimary, groupId uint64, credential string, limit uint64) ([]t.VDBPostValidatorsData, error) AddValidatorDashboardValidatorsByGraffiti(ctx context.Context, dashboardId t.VDBIdPrimary, groupId uint64, graffiti string, limit uint64) ([]t.VDBPostValidatorsData, error) RemoveValidatorDashboardValidators(ctx context.Context, dashboardId t.VDBIdPrimary, validators []t.VDBValidator) error diff --git a/backend/pkg/api/data_access/vdb_management.go b/backend/pkg/api/data_access/vdb_management.go index 6b1e6304b..db4037818 100644 --- a/backend/pkg/api/data_access/vdb_management.go +++ b/backend/pkg/api/data_access/vdb_management.go @@ -953,10 +953,10 @@ func (d *DataAccessService) AddValidatorDashboardValidatorsByDepositAddress(ctx // Updates the group for validators already in the dashboard linked to the withdrawal address. // Adds up to limit new validators associated with the withdrawal address, if not already in the dashboard. -func (d *DataAccessService) AddValidatorDashboardValidatorsByWithdrawalAddress(ctx context.Context, dashboardId t.VDBIdPrimary, groupId uint64, address string, limit uint64) ([]t.VDBPostValidatorsData, error) { +func (d *DataAccessService) AddValidatorDashboardValidatorsByWithdrawalCredential(ctx context.Context, dashboardId t.VDBIdPrimary, groupId uint64, credential string, limit uint64) ([]t.VDBPostValidatorsData, error) { result := []t.VDBPostValidatorsData{} - addressParsed, err := hex.DecodeString(strings.TrimPrefix(address, "0x")) + addressParsed, err := hex.DecodeString(strings.TrimPrefix(credential, "0x")) if err != nil { return nil, err } diff --git a/backend/pkg/api/handlers/public.go b/backend/pkg/api/handlers/public.go index f74cd6204..a628bf26c 100644 --- a/backend/pkg/api/handlers/public.go +++ b/backend/pkg/api/handlers/public.go @@ -533,7 +533,7 @@ func (h *HandlerService) PublicDeleteValidatorDashboardGroupValidators(w http.Re // @Accept json // @Produce json // @Param dashboard_id path integer true "The ID of the dashboard." -// @Param request body handlers.PublicPostValidatorDashboardValidators.request true "`group_id`: (optional) Provide a single group id, to which all validators get added to. If omitted, the default group will be used.

To add validators or update their group, only one of the following fields can be set:" +// @Param request body handlers.PublicPostValidatorDashboardValidators.request true "`group_id`: (optional) Provide a single group id, to which all validators get added to. If omitted, the default group will be used.

To add validators or update their group, only one of the following fields can be set:" // @Success 201 {object} types.ApiDataResponse[[]types.VDBPostValidatorsData] "Returns a list of added validators." // @Failure 400 {object} types.ApiErrorResponse // @Router /validator-dashboards/{dashboard_id}/validators [post] @@ -541,11 +541,11 @@ func (h *HandlerService) PublicPostValidatorDashboardValidators(w http.ResponseW var v validationError dashboardId := v.checkPrimaryDashboardId(mux.Vars(r)["dashboard_id"]) type request struct { - GroupId uint64 `json:"group_id,omitempty" x-nullable:"true"` - Validators []intOrString `json:"validators,omitempty"` - DepositAddress string `json:"deposit_address,omitempty"` - WithdrawalAddress string `json:"withdrawal_address,omitempty"` - Graffiti string `json:"graffiti,omitempty"` + GroupId uint64 `json:"group_id,omitempty" x-nullable:"true"` + Validators []intOrString `json:"validators,omitempty"` + DepositAddress string `json:"deposit_address,omitempty"` + WithdrawalCredential string `json:"withdrawal_credential,omitempty"` + Graffiti string `json:"graffiti,omitempty"` } req := request{ GroupId: types.DefaultGroupId, // default value @@ -559,11 +559,11 @@ func (h *HandlerService) PublicPostValidatorDashboardValidators(w http.ResponseW return } groupId := req.GroupId - // check if exactly one of validators, deposit_address, withdrawal_address, graffiti is set + // check if exactly one of validators, deposit_address, withdrawal_credential, graffiti is set nilFields := []bool{ req.Validators == nil, req.DepositAddress == "", - req.WithdrawalAddress == "", + req.WithdrawalCredential == "", req.Graffiti == "", } var count int @@ -573,7 +573,7 @@ func (h *HandlerService) PublicPostValidatorDashboardValidators(w http.ResponseW } } if count != 1 { - v.add("request body", "exactly one of `validators`, `deposit_address`, `withdrawal_address`, `graffiti` must be set. please check the API documentation for more information") + v.add("request body", "exactly one of `validators`, `deposit_address`, `withdrawal_credential`, `graffiti` must be set. please check the API documentation for more information") } if v.hasErrors() { handleErr(w, r, v) @@ -644,13 +644,13 @@ func (h *HandlerService) PublicPostValidatorDashboardValidators(w http.ResponseW } data, dataErr = h.getDataAccessor(r).AddValidatorDashboardValidatorsByDepositAddress(ctx, dashboardId, groupId, depositAddress, limit) - case req.WithdrawalAddress != "": - withdrawalAddress := v.checkRegex(reWithdrawalCredential, req.WithdrawalAddress, "withdrawal_address") + case req.WithdrawalCredential != "": + withdrawalCredential := v.checkRegex(reWithdrawalCredential, req.WithdrawalCredential, "withdrawal_credential") if v.hasErrors() { handleErr(w, r, v) return } - data, dataErr = h.getDataAccessor(r).AddValidatorDashboardValidatorsByWithdrawalAddress(ctx, dashboardId, groupId, withdrawalAddress, limit) + data, dataErr = h.getDataAccessor(r).AddValidatorDashboardValidatorsByWithdrawalCredential(ctx, dashboardId, groupId, withdrawalCredential, limit) case req.Graffiti != "": graffiti := v.checkRegex(reGraffiti, req.Graffiti, "graffiti")