Skip to content

Commit

Permalink
*: update v0.17 branch with latest code for release (#2528)
Browse files Browse the repository at this point in the history
The following PRs have been cherry-picked:

- #2490
- #2494
- #2496
- #2509
- #2510
- #2504
- #2511
- #2514
- #2516
- #2518


category: misc
ticket: none
  • Loading branch information
gsora authored Aug 9, 2023
1 parent 1382a92 commit 4c90ca0
Show file tree
Hide file tree
Showing 39 changed files with 776 additions and 229 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
# Config options can be found in README here: https://github.com/golangci/golangci-lint-action
- uses: actions/setup-go@v4
with:
go-version: '1.20.6'
go-version: '1.20.7'
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/govulncheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.20.6'
go-version: '1.20.7'
- run: go install golang.org/x/vuln/cmd/govulncheck@latest
- run: govulncheck -show=stacks -test ./...
2 changes: 1 addition & 1 deletion .github/workflows/nightly-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.20.6'
go-version: '1.20.7'
- uses: actions/cache@v3
with:
path: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- uses: actions/setup-python@v2
- uses: actions/setup-go@v4
with:
go-version: '1.20.6'
go-version: '1.20.7'
- uses: pre-commit/[email protected]

- name: notify failure
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
fetch-depth: 0 # Disable shallow checkout
- uses: actions/setup-go@v4
with:
go-version: '1.20.6'
go-version: '1.20.7'
- run: go run . --help > cli-reference.txt
- run: go run testutil/genchangelog/main.go
- uses: softprops/action-gh-release@v1
Expand Down
33 changes: 30 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.20.6'
go-version: '1.20.7'
- uses: actions/cache@v3
with:
path: |
Expand All @@ -33,7 +33,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.20.6'
go-version: '1.20.7'
- uses: actions/cache@v3
with:
path: |
Expand All @@ -51,7 +51,7 @@ jobs:
- uses: docker/setup-buildx-action@v2 # For compose to build images
- uses: actions/setup-go@v4
with:
go-version: '1.20.6'
go-version: '1.20.7'
- uses: actions/cache@v3
with:
path: |
Expand All @@ -71,6 +71,33 @@ jobs:
path: testutil/compose/smoke/*.log
retention-days: 3

fuzz_tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: docker/setup-buildx-action@v2 # For compose to build images
- uses: actions/setup-go@v4
with:
go-version: '1.20.7'
- uses: actions/cache@v3
with:
path: |
~/go/pkg/mod
~/.cache/go-build
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- run: |
echo "CHARON_REPO=$(pwd)" >> $GITHUB_ENV
echo "DOCKER_BUILDKIT=1" >> $GITHUB_ENV
- run: go test -race github.com/obolnetwork/charon/testutil/compose/fuzz -v -fuzzer -sudo-perms -timeout=45m -log-dir=.
- uses: actions/upload-artifact@v3
if: always()
with:
name: fuzz-test-logs
path: testutil/compose/fuzz/*.log
retention-days: 3

notify_failure:
runs-on: ubuntu-latest
needs: [ unit_tests, integration_tests, compose_tests ]
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/track-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.20.6'
go-version: '1.20.7'

- name: "Track PR"
run: go run github.com/obolnetwork/charon/testutil/trackpr
2 changes: 1 addition & 1 deletion .github/workflows/verify-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.20.6'
go-version: '1.20.7'

- name: "Verify PR"
run: go run github.com/obolnetwork/charon/testutil/verifypr
4 changes: 2 additions & 2 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
run:
timeout: 5m
go: "1.20.6"
go: "1.20.7"
linters-settings:
cyclop:
max-complexity: 15
Expand Down Expand Up @@ -89,7 +89,7 @@ linters-settings:
- "github.com/gogo/protobuf/proto" # Prefer google.golang.org/protobuf
- "github.com/prometheus/client_golang/prometheus/promauto" # Prefer ./app/promauto
staticcheck:
go: "1.20.6"
go: "1.20.7"
checks:
- "all"
- "-SA1019" # Ignoring since github.com/drand/kyber/sign/bls uses Proof Of Possession as does Ethereum.
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Container for building Go binary.
FROM golang:1.20.6-bullseye AS builder
FROM golang:1.20.7-bullseye AS builder
# Install dependencies
RUN apt-get update && apt-get install -y build-essential git
# Prep and copy source
Expand Down
6 changes: 3 additions & 3 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ func wireCoreWorkflow(ctx context.Context, life *lifecycle.Manager, conf Config,
return err
}

if err := wireVAPIRouter(life, conf.ValidatorAPIAddr, eth2Cl, vapi, vapiCalls); err != nil {
if err := wireVAPIRouter(ctx, life, conf.ValidatorAPIAddr, eth2Cl, vapi, vapiCalls); err != nil {
return err
}

Expand Down Expand Up @@ -889,10 +889,10 @@ func createMockValidators(pubkeys []eth2p0.BLSPubKey) beaconmock.ValidatorSet {
}

// wireVAPIRouter constructs the validator API router and registers it with the life cycle manager.
func wireVAPIRouter(life *lifecycle.Manager, vapiAddr string, eth2Cl eth2wrap.Client,
func wireVAPIRouter(ctx context.Context, life *lifecycle.Manager, vapiAddr string, eth2Cl eth2wrap.Client,
handler validatorapi.Handler, vapiCalls func(),
) error {
vrouter, err := validatorapi.NewRouter(handler, eth2Cl)
vrouter, err := validatorapi.NewRouter(ctx, handler, eth2Cl)
if err != nil {
return errors.Wrap(err, "new monitoring server")
}
Expand Down
55 changes: 42 additions & 13 deletions app/obolapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package obolapi
import (
"bytes"
"context"
"fmt"
"io"
"net/http"
"net/url"
Expand All @@ -15,46 +16,74 @@ import (
"github.com/obolnetwork/charon/cluster"
)

const (
// launchpadReturnPathFmt is the URL path format string at which one can find details for a given cluster lock hash.
launchpadReturnPathFmt = "/lock/0x%X/launchpad"
)

// New returns a new Client.
func New(url string) Client {
return Client{
baseURL: url,
func New(urlStr string) (Client, error) {
_, err := url.ParseRequestURI(urlStr) // check that urlStr is valid
if err != nil {
return Client{}, errors.Wrap(err, "could not parse Obol API URL")
}

return Client{
baseURL: urlStr,
}, nil
}

// Client is the REST client for obol-api requests.
type Client struct {
baseURL string // Base obol-api URL
}

// url returns a *url.URL from the baseURL stored in c.
// Will panic if somehow c.baseURL got corrupted, and it's not a valid URL anymore.
func (c Client) url() *url.URL {
baseURL, err := url.ParseRequestURI(c.baseURL)
if err != nil {
panic(errors.Wrap(err, "could not parse Obol API URL, this should never happen"))
}

return baseURL
}

// PublishLock posts the lockfile to obol-api.
func (c Client) PublishLock(ctx context.Context, lock cluster.Lock) error {
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()

addr, err := url.JoinPath(c.baseURL, "lock")
if err != nil {
return errors.Wrap(err, "invalid address")
}

url, err := url.Parse(addr)
if err != nil {
return errors.Wrap(err, "invalid endpoint")
}
addr := c.url()
addr.Path = "lock"

b, err := lock.MarshalJSON()
if err != nil {
return errors.Wrap(err, "marshal lock")
}

err = httpPost(ctx, url, b)
err = httpPost(ctx, addr, b)
if err != nil {
return err
}

return nil
}

// LaunchpadURLForLock returns the Launchpad cluster dashboard page for a given lock, on the given
// Obol API client.
func (c Client) LaunchpadURLForLock(lock cluster.Lock) string {
lURL := c.url()

lURL.Path = launchpadURLPath(lock)

return lURL.String()
}

func launchpadURLPath(lock cluster.Lock) string {
return fmt.Sprintf(launchpadReturnPathFmt, lock.LockHash)
}

func httpPost(ctx context.Context, url *url.URL, b []byte) error {
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url.String(), bytes.NewReader(b))
if err != nil {
Expand Down
49 changes: 47 additions & 2 deletions app/obolapi/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
package obolapi_test

import (
"bytes"
"context"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"net/url"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -45,8 +47,51 @@ func TestLockPublish(t *testing.T) {

lock, _, _ := cluster.NewForT(t, 3, 3, 4, 0, opts...)

cl := obolapi.New(srv.URL)
err := cl.PublishLock(ctx, lock)
cl, err := obolapi.New(srv.URL)
require.NoError(t, err)
err = cl.PublishLock(ctx, lock)
require.NoError(t, err)
})
}

func TestURLParsing(t *testing.T) {
t.Run("invalid url", func(t *testing.T) {
cl, err := obolapi.New("badURL")
require.Error(t, err)
require.Empty(t, cl)
})

t.Run("http url", func(t *testing.T) {
cl, err := obolapi.New("http://unsafe.today")
require.NoError(t, err)
require.NotEmpty(t, cl)
})

t.Run("https url", func(t *testing.T) {
cl, err := obolapi.New("https://safe.today")
require.NoError(t, err)
require.NotEmpty(t, cl)
})
}

func TestLaunchpadDashURL(t *testing.T) {
t.Run("produced url is what we expect", func(t *testing.T) {
cl, err := obolapi.New("https://safe.today")
require.NoError(t, err)
require.NotEmpty(t, cl)

result := cl.LaunchpadURLForLock(cluster.Lock{LockHash: bytes.Repeat([]byte{0x42}, 32)})

require.NotEmpty(t, result)

parsedRes, err := url.ParseRequestURI(result)
require.NoError(t, err)

require.Equal(t, "safe.today", parsedRes.Host)
require.Equal(
t,
"/lock/0x4242424242424242424242424242424242424242424242424242424242424242/launchpad",
parsedRes.Path,
)
})
}
30 changes: 23 additions & 7 deletions cmd/createcluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,14 @@ func runCreateCluster(ctx context.Context, w io.Writer, conf clusterConfig) erro
lock.NodeSignatures = append(lock.NodeSignatures, nodeSig)
}

// dashboardURL is the Launchpad dashboard url for a given lock file.
// If empty, either conf.Publish wasn't specified or there was a processing error in publishing
// the generated lock file.
var dashboardURL string

// Write cluster-lock file
if conf.Publish {
if err = writeLockToAPI(ctx, conf.PublishAddr, lock); err != nil {
if dashboardURL, err = writeLockToAPI(ctx, conf.PublishAddr, lock); err != nil {
log.Warn(ctx, "Couldn't publish lock file to Obol API", err)
}
}
Expand All @@ -272,7 +277,15 @@ func runCreateCluster(ctx context.Context, w io.Writer, conf clusterConfig) erro
writeWarning(w)
}

return writeOutput(w, conf.SplitKeys, conf.ClusterDir, numNodes, keysToDisk)
if err := writeOutput(w, conf.SplitKeys, conf.ClusterDir, numNodes, keysToDisk); err != nil {
return err
}

if dashboardURL != "" {
log.Info(ctx, fmt.Sprintf("You can find your newly-created cluster dashboard here: %s", dashboardURL))
}

return nil
}

// validateCreateConfig returns an error if any of the provided config parameters are invalid.
Expand Down Expand Up @@ -943,17 +956,20 @@ func randomHex64() (string, error) {
return hex.EncodeToString(b), nil
}

// writeLockToAPI posts the lock file to obol-api.
func writeLockToAPI(ctx context.Context, publishAddr string, lock cluster.Lock) error {
cl := obolapi.New(publishAddr)
// writeLockToAPI posts the lock file to obol-api and returns the Launchpad dashboard URL.
func writeLockToAPI(ctx context.Context, publishAddr string, lock cluster.Lock) (string, error) {
cl, err := obolapi.New(publishAddr)
if err != nil {
return "", err
}

if err := cl.PublishLock(ctx, lock); err != nil {
return err
return "", err
}

log.Info(ctx, "Published lock file", z.Str("addr", publishAddr))

return nil
return cl.LaunchpadURLForLock(lock), nil
}

// validateAddresses checks if we have sufficient addresses. It also fills addresses slices if only one is provided.
Expand Down
Loading

0 comments on commit 4c90ca0

Please sign in to comment.