Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge staging->main #1143

Closed
wants to merge 37 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
2f208d5
Merge pull request #1126 from gobitfly/main
guybrush Nov 13, 2024
310860a
refactor: remove `network average`
benji-bitfly Nov 13, 2024
e5e6539
chore(rocketpool-exporter): improve logging (#1128)
guybrush Nov 14, 2024
2fcc2b8
feat(notifications): add metadata to client update notifications
peterbitfly Nov 14, 2024
d8a2ade
feat(BEDS-880): improve queries when adding validators to the dashboard
Eisei24 Nov 12, 2024
cf8264c
fix(BEDS-880): Use the correct writer
Eisei24 Nov 14, 2024
08fe21d
fix(notifications): use correct col name in webhook update query
peterbitfly Nov 15, 2024
5d42a69
feat(indexer): verify rewinding before continuing at start
Tangui-Bitfly Nov 15, 2024
04610e2
fix(ci): remove rule testpackage + use conf file in CI
Tangui-Bitfly Nov 15, 2024
7022af5
Added webhook notifications toggle
Eisei24 Nov 7, 2024
58108fc
Fixed frontend issue
Eisei24 Nov 7, 2024
308e4a3
chore(logging): add version to error logs
guybrush Nov 20, 2024
2167f00
feat(api): add x-beaconchain-version header to all responses
guybrush Nov 20, 2024
a6e286a
fix(api): fix version-middleware
guybrush Nov 20, 2024
ed62345
fix(api): fix version-middleware
guybrush Nov 20, 2024
5fde769
Merge branch 'main' into staging
guybrush Nov 20, 2024
4c50f64
fix(config): enable optional ssl for user db connections
peterbitfly Nov 21, 2024
ab7751d
feat: add mobile validators endpoint with extra data fields
manuelsc Nov 19, 2024
6dea84d
docs(decision):add conventional commits
marcel-bitfly Nov 12, 2024
b54a0b8
docs(decision): clarify branch naming
peterbitfly Nov 15, 2024
557b130
feat: rocket pool exporter now exports the smoothing pool address for…
manuelsc Nov 21, 2024
109f207
use validator table directly for updating indices
manuelsc Nov 21, 2024
56aca37
fix(dashboard): change Dolhpin Weekly Aggregated Chart Summary Histor…
sasha-bitfly Nov 21, 2024
dec461c
ci: build and push docker-images for staging-2
guybrush Nov 11, 2024
64b6716
refactor: rename search types and handlers file
LuccaBitfly Nov 6, 2024
5a60343
refactor: better search result types
LuccaBitfly Nov 6, 2024
1d66096
refactor: rename withdrawal_address to withdrawal_credential
LuccaBitfly Nov 15, 2024
2101477
style(nuxt.config): remove comments
marcel-bitfly Nov 7, 2024
868fb43
fix(App): add current `lang attribute` to `<html>`
marcel-bitfly Nov 7, 2024
b0a058e
feat(healthz): change route from `frontend` to `(nuxt) backend`
marcel-bitfly Nov 19, 2024
f42a968
feat(dashboards): add `bulk adding` via `comma seperated values` to `…
marcel-bitfly Nov 19, 2024
9469ebe
chore(color-mode): change to `dark mode` by default
Buttaa Nov 19, 2024
ef18702
fix(BcPremiumModal): only `close dialog` on `esc`
marcel-bitfly Nov 20, 2024
ef6f5a2
refactor: remove accidentillay `checked in` file
marcel-bitfly Nov 22, 2024
d7e7c9e
chore(dependabot): add `version update` feature
marcel-bitfly Nov 22, 2024
9fd473e
chore(dependabot): adapt `commit msg`
marcel-bitfly Nov 22, 2024
1a2879b
chore(update): dependencies to fix `vulnerabilities`
marcel-bitfly Nov 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: 2
updates:
- package-ecosystem: "npm"
directory: "/frontend"
schedule:
interval: "weekly"
time: "05:00"
timezone: "Europe/Berlin"
target-branch: "staging"
assignees:
- "marcel-bitfly"
- "benji-bitfly"
commit-message:
prefix: "chore(update)"
2 changes: 1 addition & 1 deletion .github/workflows/backend-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
with:
version: v1.60.1
working-directory: backend
args: --timeout=5m
args: --timeout=5m --config .golangci.yml



1 change: 1 addition & 0 deletions .github/workflows/backend-publish-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/frontend-publish-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions backend/.golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ linters:
- importas
- unparam
disable:
- testpackage
- dupword
- gocognit
- dupl
Expand Down
1 change: 1 addition & 0 deletions backend/cmd/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func Run() {
dummy := dataaccess.NewDummyService()

router := api.NewApiRouter(dataAccessor, dummy, cfg)
router.Use(version.HttpMiddleware)
router.Use(api.GetCorsMiddleware(cfg.CorsAllowedHosts))

if utils.Config.Metrics.Enabled {
Expand Down
59 changes: 38 additions & 21 deletions backend/cmd/evm_node_indexer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,22 @@ import (
"sync/atomic"
"time"

gcp_bigtable "cloud.google.com/go/bigtable"
"github.com/ethereum/go-ethereum"
gethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/gtuk/discordwebhook"
"github.com/lib/pq"
"golang.org/x/sync/errgroup"
"google.golang.org/api/option"

"github.com/gobitfly/beaconchain/pkg/commons/db"
"github.com/gobitfly/beaconchain/pkg/commons/hexutil"
"github.com/gobitfly/beaconchain/pkg/commons/log"
"github.com/gobitfly/beaconchain/pkg/commons/metrics"
"github.com/gobitfly/beaconchain/pkg/commons/types"
"github.com/gobitfly/beaconchain/pkg/commons/utils"
"github.com/gobitfly/beaconchain/pkg/commons/version"
"github.com/gtuk/discordwebhook"
"github.com/lib/pq"
"golang.org/x/sync/errgroup"
"google.golang.org/api/option"

gcp_bigtable "cloud.google.com/go/bigtable"
)

// defines
Expand Down Expand Up @@ -86,12 +86,18 @@ type intRange struct {

// local globals
var currentNodeBlockNumber atomic.Int64
var elClient *ethclient.Client
var elClient ethClient
var reorgDepth *int64
var httpClient *http.Client
var errorIdentifier *regexp.Regexp
var eth1RpcEndpoint string

type ethClient interface {
SubscribeNewHead(ctx context.Context, ch chan<- *gethtypes.Header) (ethereum.Subscription, error)
ethereum.ChainIDReader
ethereum.BlockNumberReader
}

// init
func init() {
httpClient = &http.Client{Timeout: time.Second * HTTP_TIMEOUT_IN_SECONDS}
Expand Down Expand Up @@ -275,7 +281,9 @@ func Run() {

// get latest block (as it's global, so we have a initial value)
log.Info("get latest block from node...")
updateBlockNumber(true, *noNewBlocks, time.Duration(*noNewBlocksThresholdSeconds)*time.Second, discordWebhookReportUrl, discordWebhookUser, discordWebhookAddTextFatal)
if err := updateBlockNumber(*noNewBlocks, time.Duration(*noNewBlocksThresholdSeconds)*time.Second, discordWebhookReportUrl, discordWebhookUser, discordWebhookAddTextFatal); err != nil {
log.Fatal(err, "updateBlockNumber", 0)
}
log.Infof("...get latest block (%s) from node done.", _formatInt64(currentNodeBlockNumber.Load()))

// //////////////////////////////////////////
Expand Down Expand Up @@ -892,21 +900,30 @@ func _splitAndVerifyJsonArray(jArray []byte, providedElementCount int64) ([][]by
return r, nil
}

// get newest block number from node, should be called always with TRUE
func updateBlockNumber(firstCall bool, noNewBlocks bool, noNewBlocksThresholdDuration time.Duration, discordWebhookReportUrl *string, discordWebhookUser *string, discordWebhookAddTextFatal *string) {
if firstCall {
blockNumber, err := rpciGetLatestBlock()
if err != nil {
sendMessage(fmt.Sprintf("%s NODE EXPORT: Fatal, failed to get newest block from node, on first try %s", getChainNamePretty(), *discordWebhookAddTextFatal), discordWebhookReportUrl, discordWebhookUser)
log.Fatal(err, "fatal, failed to get newest block from node, on first try", 0)
}
currentNodeBlockNumber.Store(blockNumber)
if !noNewBlocks {
go updateBlockNumber(false, false, noNewBlocksThresholdDuration, discordWebhookReportUrl, discordWebhookUser, discordWebhookAddTextFatal)
}
return
// get newest block number from node
func updateBlockNumber(noNewBlocks bool, noNewBlocksThresholdDuration time.Duration, discordWebhookReportUrl *string, discordWebhookUser *string, discordWebhookAddTextFatal *string) error {
blockNumber, err := rpciGetLatestBlock()
if err != nil {
sendMessage(fmt.Sprintf("%s NODE EXPORT: Fatal, failed to get newest block from node, on first try %s", getChainNamePretty(), *discordWebhookAddTextFatal), discordWebhookReportUrl, discordWebhookUser)
log.Fatal(err, "fatal, failed to get newest block from node, on first try", 0)
}
currentNodeBlockNumber.Store(blockNumber)
// request the block number a second time to verify if node is not rewinding
blockNumber, err = rpciGetLatestBlock()
if err != nil {
return err
}
if blockNumber < currentNodeBlockNumber.Load() {
return fmt.Errorf("node is rewinding: newest block %d < previous block %d", blockNumber, currentNodeBlockNumber.Load())
}

if !noNewBlocks {
go monitorBlockNumber(noNewBlocksThresholdDuration, discordWebhookReportUrl, discordWebhookUser, discordWebhookAddTextFatal)
}
return nil
}

func monitorBlockNumber(noNewBlocksThresholdDuration time.Duration, discordWebhookReportUrl *string, discordWebhookUser *string, discordWebhookAddTextFatal *string) {
var errorText string
gotNewBlockAt := time.Now()
timePerBlock := time.Second * time.Duration(utils.Config.Chain.ClConfig.SecondsPerSlot)
Expand Down
55 changes: 55 additions & 0 deletions backend/cmd/evm_node_indexer/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package evm_node_indexer

import (
"context"
"math/big"
"strings"
"testing"
"time"

"github.com/ethereum/go-ethereum"
gethtypes "github.com/ethereum/go-ethereum/core/types"

"github.com/gobitfly/beaconchain/pkg/commons/types"
"github.com/gobitfly/beaconchain/pkg/commons/utils"
)

func TestUpdateBlockNumberWithRewindingNode(t *testing.T) {
utils.Config = &types.Config{
Chain: types.Chain{
ClConfig: types.ClChainConfig{
SecondsPerSlot: 0,
},
},
}
elClient = &fakeEthClient{
chainID: big.NewInt(1),
blocks: []uint64{126192682, 126186030},
}
err := updateBlockNumber(false, time.Second, nil, nil, nil)
if err == nil {
t.Fatal("expected error got nil")
}
if !strings.Contains(err.Error(), "node is rewinding") {
t.Fatalf("error message does not contain 'node is rewinding', got %s", err.Error())
}
}

type fakeEthClient struct {
chainID *big.Int
blocks []uint64
}

func (f *fakeEthClient) SubscribeNewHead(ctx context.Context, ch chan<- *gethtypes.Header) (ethereum.Subscription, error) {
panic("implement me")
}

func (f *fakeEthClient) ChainID(ctx context.Context) (*big.Int, error) {
return f.chainID, nil
}

func (f *fakeEthClient) BlockNumber(ctx context.Context) (uint64, error) {
block := f.blocks[0]
f.blocks = f.blocks[1:]
return block, nil
}
15 changes: 9 additions & 6 deletions backend/pkg/api/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}
Expand All @@ -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{}
Expand All @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions backend/pkg/api/data_access/data_access.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ func createDataAccessService(cfg *types.Config) *DataAccessService {
Port: cfg.Frontend.WriterDatabase.Port,
MaxOpenConns: cfg.Frontend.WriterDatabase.MaxOpenConns,
MaxIdleConns: cfg.Frontend.WriterDatabase.MaxIdleConns,
SSL: cfg.Frontend.WriterDatabase.SSL,
},
&types.DatabaseConfig{
Username: cfg.Frontend.ReaderDatabase.Username,
Expand All @@ -199,6 +200,7 @@ func createDataAccessService(cfg *types.Config) *DataAccessService {
Port: cfg.Frontend.ReaderDatabase.Port,
MaxOpenConns: cfg.Frontend.ReaderDatabase.MaxOpenConns,
MaxIdleConns: cfg.Frontend.ReaderDatabase.MaxIdleConns,
SSL: cfg.Frontend.ReaderDatabase.SSL,
}, "pgx", "postgres",
)
}()
Expand Down
12 changes: 6 additions & 6 deletions backend/pkg/api/data_access/dummy.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -784,7 +784,7 @@ func (d *DummyService) PostUserMachineMetrics(ctx context.Context, userID uint64
return nil
}

func (d *DummyService) GetValidatorDashboardMobileValidators(ctx context.Context, dashboardId t.VDBId, period enums.TimePeriod, cursor string, colSort t.Sort[enums.VDBMobileValidatorsColumn], search string, limit uint64) ([]t.MobileValidatorDashboardValidatorsTableRow, *t.Paging, error) {
func (d *DummyService) GetValidatorDashboardMobileValidators(ctx context.Context, dashboardId t.VDBId, groupId int64, period enums.TimePeriod, cursor string, colSort t.Sort[enums.VDBManageValidatorsColumn], search string, limit uint64) ([]t.MobileValidatorDashboardValidatorsTableRow, *t.Paging, error) {
return getDummyWithPaging[t.MobileValidatorDashboardValidatorsTableRow](ctx)
}

Expand Down
Loading
Loading