Skip to content

Commit

Permalink
Merge branch 'stage' of github.com:bloxapp/ssv into feat/add-degradat…
Browse files Browse the repository at this point in the history
…ion-tests-into-ci
  • Loading branch information
AKorpusenko committed Apr 1, 2024
2 parents f31259b + ef80171 commit 03ed165
Show file tree
Hide file tree
Showing 79 changed files with 1,588 additions and 1,357 deletions.
20 changes: 3 additions & 17 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,6 @@ RUN apt-get update && \
make=4.3-4.1 \
&& rm -rf /var/lib/apt/lists/*

# install jemalloc
WORKDIR /tmp/jemalloc-temp
RUN curl -s -L "https://github.com/jemalloc/jemalloc/releases/download/5.2.1/jemalloc-5.2.1.tar.bz2" -o jemalloc.tar.bz2 \
&& tar xjf ./jemalloc.tar.bz2
RUN cd jemalloc-5.2.1 \
&& ./configure --with-jemalloc-prefix='je_' --with-malloc-conf='background_thread:true,metadata_thp:auto' \
&& make && make install

RUN go version

WORKDIR /go/src/github.com/bloxapp/ssv/
Expand All @@ -46,22 +38,16 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
COMMIT=$(git rev-parse HEAD) && \
VERSION=$(git describe --tags $(git rev-list --tags --max-count=1) --always) && \
CGO_ENABLED=1 GOOS=linux go install \
-tags="blst_enabled,jemalloc,allocator" \
-tags="blst_enabled" \
-ldflags "-X main.Commit=$COMMIT -X main.Version=$VERSION -linkmode external -extldflags \"-static -lm\"" \
./cmd/ssvnode

#
# STEP 3: Prepare image to run the binary
#
FROM alpine:3.18.3 AS runner
FROM golang:1.20.7 AS runner

# Install ca-certificates, bash
RUN apk -v --update add \
ca-certificates=20240226-r0 \
bash=5.2.15-r5 \
make=4.4.1-r1 \
bind-tools=9.18.24-r0 && \
rm /var/cache/apk/*
WORKDIR /

COPY --from=builder /go/bin/ssvnode /go/bin/ssvnode
COPY ./Makefile .env* ./
Expand Down
10 changes: 4 additions & 6 deletions beacon/goclient/goclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"go.uber.org/zap"

"github.com/bloxapp/ssv/logging/fields"
"github.com/bloxapp/ssv/message/validation"
operatordatastore "github.com/bloxapp/ssv/operator/datastore"
"github.com/bloxapp/ssv/operator/slotticker"
beaconprotocol "github.com/bloxapp/ssv/protocol/v2/blockchain/beacon"
)
Expand Down Expand Up @@ -150,7 +150,7 @@ type goClient struct {
nodeClient NodeClient
graffiti []byte
gasLimit uint64
getOperatorID validation.OperatorIDGetter
operatorDataStore operatordatastore.OperatorDataStore
registrationMu sync.Mutex
registrationLastSlot phase0.Slot
registrationCache map[phase0.BLSPubKey]*api.VersionedSignedValidatorRegistration
Expand All @@ -162,7 +162,7 @@ type goClient struct {
func New(
logger *zap.Logger,
opt beaconprotocol.Options,
getOperatorID validation.OperatorIDGetter,
operatorDataStore operatordatastore.OperatorDataStore,
slotTickerProvider slotticker.Provider,
) (beaconprotocol.BeaconNode, error) {
logger.Info("consensus client: connecting", fields.Address(opt.BeaconNodeAddr), fields.Network(string(opt.Network.BeaconNetwork)))
Expand Down Expand Up @@ -194,13 +194,12 @@ func New(
client: httpClient.(*eth2clienthttp.Service),
graffiti: opt.Graffiti,
gasLimit: opt.GasLimit,
getOperatorID: getOperatorID,
operatorDataStore: operatorDataStore,
registrationCache: map[phase0.BLSPubKey]*api.VersionedSignedValidatorRegistration{},
commonTimeout: commonTimeout,
longTimeout: longTimeout,
}

// Get the node's version and client.
nodeVersionResp, err := client.client.NodeVersion(opt.Context, &api.NodeVersionOpts{})
if err != nil {
return nil, fmt.Errorf("failed to get node version: %w", err)
Expand All @@ -218,7 +217,6 @@ func New(
zap.String("version", client.nodeVersion),
)

// Start registration submitter.
go client.registrationSubmitter(slotTickerProvider)

return client, nil
Expand Down
4 changes: 3 additions & 1 deletion beacon/goclient/goclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ import (
"github.com/stretchr/testify/require"
"go.uber.org/zap"

operatordatastore "github.com/bloxapp/ssv/operator/datastore"
"github.com/bloxapp/ssv/operator/slotticker"
"github.com/bloxapp/ssv/protocol/v2/blockchain/beacon"
registrystorage "github.com/bloxapp/ssv/registry/storage"
)

func TestTimeouts(t *testing.T) {
Expand Down Expand Up @@ -94,7 +96,7 @@ func mockClient(t *testing.T, ctx context.Context, serverURL string, commonTimeo
CommonTimeout: commonTimeout,
LongTimeout: longTimeout,
},
func() types.OperatorID { return 0 },
operatordatastore.New(&registrystorage.OperatorData{ID: 1}),
func() slotticker.SlotTicker {
return slotticker.New(zap.NewNop(), slotticker.Config{
SlotDuration: 12 * time.Second,
Expand Down
9 changes: 6 additions & 3 deletions beacon/goclient/proposer.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/attestantio/go-eth2-client/spec/capella"
"github.com/attestantio/go-eth2-client/spec/deneb"
"github.com/attestantio/go-eth2-client/spec/phase0"
spectypes "github.com/bloxapp/ssv-spec/types"
ssz "github.com/ferranbt/fastssz"
"go.uber.org/zap"

Expand Down Expand Up @@ -378,18 +379,20 @@ func (gc *goClient) createValidatorRegistration(pubkey []byte, feeRecipient bell
}

func (gc *goClient) registrationSubmitter(slotTickerProvider slotticker.Provider) {
operatorID := gc.operatorDataStore.AwaitOperatorID()

ticker := slotTickerProvider()
for {
select {
case <-gc.ctx.Done():
return
case <-ticker.Next():
gc.submitRegistrationsFromCache(ticker.Slot())
gc.submitRegistrationsFromCache(ticker.Slot(), operatorID)
}
}
}

func (gc *goClient) submitRegistrationsFromCache(currentSlot phase0.Slot) {
func (gc *goClient) submitRegistrationsFromCache(currentSlot phase0.Slot, operatorID spectypes.OperatorID) {
slotsPerEpoch := gc.network.SlotsPerEpoch()

// Lock:
Expand All @@ -398,7 +401,7 @@ func (gc *goClient) submitRegistrationsFromCache(currentSlot phase0.Slot) {
gc.registrationMu.Lock()

slotsSinceLastRegistration := currentSlot - gc.registrationLastSlot
operatorSubmissionSlotModulo := gc.getOperatorID() % slotsPerEpoch
operatorSubmissionSlotModulo := operatorID % slotsPerEpoch

hasRegistrations := len(gc.registrationCache) != 0
operatorSubmissionSlot := uint64(currentSlot)%slotsPerEpoch == operatorSubmissionSlotModulo
Expand Down
67 changes: 19 additions & 48 deletions cli/generate_operator_keys.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
package cli

import (
"encoding/base64"
"encoding/json"
"github.com/bloxapp/ssv/operator/keystore"
"log"
"os"
"path/filepath"

"github.com/bloxapp/ssv/logging"
"github.com/bloxapp/ssv/utils/rsaencryption"
"github.com/spf13/cobra"
"github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4"
"go.uber.org/zap"

"github.com/bloxapp/ssv/logging"
"github.com/bloxapp/ssv/operator/keys"
)

var generateOperatorKeysCmd = &cobra.Command{
Expand All @@ -21,11 +20,12 @@ var generateOperatorKeysCmd = &cobra.Command{
if err := logging.SetGlobalLogger("debug", "capital", "console", nil); err != nil {
log.Fatal(err)
}

logger := zap.L().Named(logging.NameExportKeys)
passwordFilePath, _ := cmd.Flags().GetString("password-file")
privateKeyFilePath, _ := cmd.Flags().GetString("operator-key-file")

pk, sk, err := rsaencryption.GenerateKeys()
privKey, err := keys.GeneratePrivateKey()
if err != nil {
logger.Fatal("Failed to generate keys", zap.Error(err))
}
Expand All @@ -35,71 +35,42 @@ var generateOperatorKeysCmd = &cobra.Command{
if err != nil {
logger.Fatal("Failed to read private key from file", zap.Error(err))
}
sk, pk, err = parsePrivateKey(keyBytes)

privKey, err = keys.PrivateKeyFromString(string(keyBytes))
if err != nil {
logger.Fatal("Failed to read private key from file", zap.Error(err))
logger.Fatal("Failed to parse private key", zap.Error(err))
}
}

pubKeyBase64, err := privKey.Public().Base64()
if err != nil {
logger.Fatal("Failed to get public key PEM", zap.Error(err))
}

if passwordFilePath != "" {
passwordBytes, err := readFile(passwordFilePath)
if err != nil {
logger.Fatal("Failed to read password file", zap.Error(err))
}
encryptedJSON, encryptedJSONErr := encryptPrivateKey(sk, pk, passwordBytes)

encryptedJSON, encryptedJSONErr := keystore.EncryptKeystore(privKey.Bytes(), string(pubKeyBase64), string(passwordBytes))
if encryptedJSONErr != nil {
logger.Fatal("Failed to encrypt private key", zap.Error(err))
}

err = writeFile("encrypted_private_key.json", encryptedJSON)
if err != nil {
logger.Fatal("Failed to save private key", zap.Error(err))
} else {
logger.Info("private key encrypted and stored in encrypted_private_key.json")
}
} else {
logger.Info("generated public key (base64)", zap.String("pk", base64.StdEncoding.EncodeToString(pk)))
logger.Info("generated private key (base64)", zap.String("sk", base64.StdEncoding.EncodeToString(sk)))
logger.Info("generated public key (base64)", zap.String("pk", string(pubKeyBase64)))
logger.Info("generated private key (base64)", zap.String("sk", string(privKey.Base64())))
}
},
}

func parsePrivateKey(keyBytes []byte) ([]byte, []byte, error) {
decodedBytes, err := base64.StdEncoding.DecodeString(string(keyBytes))
if err != nil {
return nil, nil, err
}
rsaKey, err := rsaencryption.ConvertPemToPrivateKey(string(decodedBytes))
if err != nil {
return nil, nil, err
}

skPem := rsaencryption.PrivateKeyToByte(rsaKey)

operatorPublicKey, err := rsaencryption.ExtractPublicKey(rsaKey)
if err != nil {
return nil, nil, err
}
pk, err := base64.StdEncoding.DecodeString(operatorPublicKey)
if err != nil {
return nil, nil, err
}
return skPem, pk, nil
}

func encryptPrivateKey(sk []byte, pk []byte, passwordBytes []byte) ([]byte, error) {
encryptionPassword := string(passwordBytes)
encryptedData, err := keystorev4.New().Encrypt(sk, encryptionPassword)
if err != nil {
return nil, err
}
encryptedData["publicKey"] = base64.StdEncoding.EncodeToString(pk)
encryptedJSON, err := json.Marshal(encryptedData)
if err != nil {
return nil, err
}
return encryptedJSON, nil
}

func writeFile(fileName string, data []byte) error {
return os.WriteFile(fileName, data, 0600)
}
Expand Down
Loading

0 comments on commit 03ed165

Please sign in to comment.