From 2de450b7a1c1eb4887747937982449df26d9ccb1 Mon Sep 17 00:00:00 2001 From: olegshmuelov <45327364+olegshmuelov@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:30:38 +0200 Subject: [PATCH] improvements --- e2e/cmd/ssv-e2e/beacon_proxy.go | 15 ++- e2e/cmd/ssv-e2e/logs_catcher.go | 50 +++++---- e2e/cmd/ssv-e2e/main.go | 1 + e2e/cmd/ssv-e2e/share_update.go | 176 +++++++++++++++++++++----------- e2e/docker-compose.yml | 11 +- e2e/logs_catcher/matcher.go | 3 +- e2e/logs_catcher/matcher_bls.go | 15 +-- e2e/run.sh | 10 +- e2e/validators.json | 79 ++++++++------ 9 files changed, 224 insertions(+), 136 deletions(-) diff --git a/e2e/cmd/ssv-e2e/beacon_proxy.go b/e2e/cmd/ssv-e2e/beacon_proxy.go index 5f9f6c000c..1f410e1b87 100644 --- a/e2e/cmd/ssv-e2e/beacon_proxy.go +++ b/e2e/cmd/ssv-e2e/beacon_proxy.go @@ -4,10 +4,11 @@ import ( "context" "encoding/json" "fmt" - "github.com/attestantio/go-eth2-client/http" "os" "time" + "github.com/attestantio/go-eth2-client/http" + eth2client "github.com/attestantio/go-eth2-client" "github.com/attestantio/go-eth2-client/auto" "github.com/attestantio/go-eth2-client/spec/phase0" @@ -30,6 +31,10 @@ type BeaconProxyCmd struct { BasePort int ` env:"BASE_PORT" help:"Base port for the gateways." default:"6631"` } +type BeaconProxyJSON struct { + Validators map[phase0.ValidatorIndex]string `json:"beacon_proxy"` +} + func GetValidators(ctx context.Context, beaconURL string, idxs []phase0.ValidatorIndex) (map[phase0.ValidatorIndex]*v1.Validator, error) { // todo: maybe create the client on top and pass down to all components client, err := auto.New( @@ -79,17 +84,17 @@ func (cmd *BeaconProxyCmd) Run(logger *zap.Logger, globals Globals) error { } logger.Info("Beacon client status OK") - var validators map[phase0.ValidatorIndex]string // dx => tests contents, err := os.ReadFile(globals.ValidatorsFile) if err != nil { return fmt.Errorf("failed to read file contents: %s, %w", globals.ValidatorsFile, err) } - err = json.Unmarshal(contents, &validators) - if err != nil { + + var beaconProxyJSON BeaconProxyJSON // dx => tests + if err = json.Unmarshal(contents, &beaconProxyJSON); err != nil { return fmt.Errorf("error parsing json file: %s, %w", globals.ValidatorsFile, err) } - validatorsData, err := GetValidators(ctx, cmd.BeaconNodeUrl, maps.Keys(validators)) + validatorsData, err := GetValidators(ctx, cmd.BeaconNodeUrl, maps.Keys(beaconProxyJSON.Validators)) if err != nil { return fmt.Errorf("failed to get validators data from beacon node err:%v", err) } diff --git a/e2e/cmd/ssv-e2e/logs_catcher.go b/e2e/cmd/ssv-e2e/logs_catcher.go index ab23a8ede4..a5c9102014 100644 --- a/e2e/cmd/ssv-e2e/logs_catcher.go +++ b/e2e/cmd/ssv-e2e/logs_catcher.go @@ -2,7 +2,9 @@ package main import ( "context" + "encoding/json" "fmt" + "os" "go.uber.org/zap" @@ -11,8 +13,7 @@ import ( ) type LogsCatcherCmd struct { - Mode string `required:"" env:"Mode" help:"Mode of the logs catcher. Can be Slashing or BlsVerification"` - Leader int `env:"Leader" help:"Leader to run the bls verification on"` + Mode string `required:"" env:"Mode" help:"Mode of the logs catcher. Can be Slashing or BlsVerification"` } const ( @@ -20,6 +21,10 @@ const ( BlsVerificationMode = "BlsVerification" ) +type BlsVerificationJSON struct { + CorruptedShares []*logs_catcher.CorruptedShare `json:"bls_verification"` +} + func (cmd *LogsCatcherCmd) Run(logger *zap.Logger, globals Globals) error { // TODO: where do we stop? ctx := context.Background() @@ -48,27 +53,15 @@ func (cmd *LogsCatcherCmd) Run(logger *zap.Logger, globals Globals) error { case BlsVerificationMode: logger.Info("Running BlsVerification mode") - var corruptedShare logs_catcher.CorruptedShare - switch cmd.Leader { - case 1: - corruptedShare = logs_catcher.CorruptedShare{ - OperatorID: 2, - ValidatorPubKey: "8c5801d7a18e27fae47dfdd99c0ac67fbc6a5a56bb1fc52d0309626d805861e04eaaf67948c18ad50c96d63e44328ab0", - ValidatorIndex: fmt.Sprintf("v%d", 1476356), - } - - case 2: - corruptedShare = logs_catcher.CorruptedShare{ - OperatorID: 2, - ValidatorPubKey: "a238aa8e3bd1890ac5def81e1a693a7658da491ac087d92cee870ab4d42998a184957321d70cbd42f9d38982dd9a928c", - ValidatorIndex: fmt.Sprintf("v%d", 1476357), - } - default: - return fmt.Errorf("invalid leader: %d", cmd.Leader) + corruptedShares, err := UnmarshalBlsVerificationJSON(globals.ValidatorsFile) + if err != nil { + return fmt.Errorf("failed to unmarshal bls verification json: %w", err) } - if err = logs_catcher.VerifyBLSSignature(ctx, logger, cli, corruptedShare); err != nil { - return err + for _, corruptedShare := range corruptedShares { + if err = logs_catcher.VerifyBLSSignature(ctx, logger, cli, corruptedShare); err != nil { + return fmt.Errorf("failed to verify BLS signature for validator index %d: %w", corruptedShare.ValidatorIndex, err) + } } default: @@ -77,3 +70,18 @@ func (cmd *LogsCatcherCmd) Run(logger *zap.Logger, globals Globals) error { return nil } + +// UnmarshalBlsVerificationJSON reads the JSON file and unmarshals it into []*CorruptedShare. +func UnmarshalBlsVerificationJSON(filePath string) ([]*logs_catcher.CorruptedShare, error) { + contents, err := os.ReadFile(filePath) + if err != nil { + return nil, fmt.Errorf("error reading json file for BLS verification: %s, %w", filePath, err) + } + + var blsVerificationJSON BlsVerificationJSON + if err = json.Unmarshal(contents, &blsVerificationJSON); err != nil { + return nil, fmt.Errorf("error parsing json file for BLS verification: %s, %w", filePath, err) + } + + return blsVerificationJSON.CorruptedShares, nil +} diff --git a/e2e/cmd/ssv-e2e/main.go b/e2e/cmd/ssv-e2e/main.go index 2c7b4488e9..a459529962 100644 --- a/e2e/cmd/ssv-e2e/main.go +++ b/e2e/cmd/ssv-e2e/main.go @@ -12,6 +12,7 @@ import ( ) type Globals struct { + NetworkName string `env:"NETWORK" default:"holesky-e2e" help:"Network config name"` LogLevel string `env:"LOG_LEVEL" enum:"debug,info,warn,error" default:"debug" help:"Log level."` LogFormat string `env:"LOG_FORMAT" enum:"console,json" default:"console" help:"Log format."` ValidatorsFile string `env:"VALIDATORS_FILE" default:"./validators.json" help:"Path to the validators.json file." type:"path"` diff --git a/e2e/cmd/ssv-e2e/share_update.go b/e2e/cmd/ssv-e2e/share_update.go index 6a42fc2e2b..dff4277aa1 100644 --- a/e2e/cmd/ssv-e2e/share_update.go +++ b/e2e/cmd/ssv-e2e/share_update.go @@ -5,39 +5,64 @@ import ( "encoding/base64" "encoding/hex" "fmt" + "os" + "github.com/bloxapp/ssv-spec/types" "github.com/bloxapp/ssv/ekm" "github.com/bloxapp/ssv/networkconfig" operatorstorage "github.com/bloxapp/ssv/operator/storage" "github.com/bloxapp/ssv/storage/basedb" "github.com/bloxapp/ssv/storage/kv" + "github.com/bloxapp/ssv/utils/blskeygen" "github.com/bloxapp/ssv/utils/rsaencryption" - "github.com/herumi/bls-eth-go-binary/bls" "go.uber.org/zap" + "gopkg.in/yaml.v3" + + "github.com/bloxapp/ssv/e2e/logs_catcher" ) type ShareUpdateCmd struct { - NetworkName string `required:"" env:"NETWORK" env-description:"Network config name"` - DBPath string `required:"" env:"DB_PATH" help:"Path to the DB folder"` - OperatorPrivateKey string `required:"" env:"OPERATOR_KEY" env-description:"Operator private key"` - ValidatorPubKey string `required:"" env:"VALIDATOR_PUB_KEY" env-description:"Validator public key"` + OperatorPrivateKey string `yaml:"OperatorPrivateKey"` } const ( - // secret key to be used for updated share - skLeader1 = "3548db63ab5701878daf25fa877638dc7809778815b9d9ecd5369da33ca9e64f" - skLeader2 = "66dd37ae71b35c81022cdde98370e881cff896b689fa9136917f45afce43fd3b" - vpkLeader1 = "8c5801d7a18e27fae47dfdd99c0ac67fbc6a5a56bb1fc52d0309626d805861e04eaaf67948c18ad50c96d63e44328ab0" // leader 1 - vpkLeader2 = "a238aa8e3bd1890ac5def81e1a693a7658da491ac087d92cee870ab4d42998a184957321d70cbd42f9d38982dd9a928c" // leader 2 + dbPathFormat = "/ssv-node-%d-data/db" + shareYAMLPath = "/tconfig/share%d.yaml" ) func (cmd *ShareUpdateCmd) Run(logger *zap.Logger, globals Globals) error { - // Setup DB - db, err := kv.New(logger, basedb.Options{ - Path: cmd.DBPath, - }) + networkConfig, err := networkconfig.GetNetworkConfigByName(globals.NetworkName) + if err != nil { + return fmt.Errorf("failed to get network config: %w", err) + } + + corruptedShares, err := UnmarshalBlsVerificationJSON(globals.ValidatorsFile) if err != nil { - return fmt.Errorf("failed to open db: %w", err) + return fmt.Errorf("failed to unmarshal bls verification json: %w", err) + } + + operatorSharesMap := buildOperatorCorruptedSharesMap(corruptedShares) + + for operatorID, operatorCorruptedShares := range operatorSharesMap { + // Read OperatorPrivateKey from the YAML file + operatorPrivateKey, err := readOperatorPrivateKeyFromFile(fmt.Sprintf(shareYAMLPath, operatorID)) + if err != nil { + return err + } + + if err := Process(logger, networkConfig, operatorPrivateKey, operatorID, operatorCorruptedShares); err != nil { + return fmt.Errorf("failed to process operator %d: %w", operatorID, err) + } + } + + return nil +} + +func Process(logger *zap.Logger, networkConfig networkconfig.NetworkConfig, operatorPrivateKey string, operatorID types.OperatorID, operatorCorruptedShares []*logs_catcher.CorruptedShare) error { + dbPath := fmt.Sprintf(dbPathFormat, operatorID) + db, err := openDB(logger, dbPath) + if err != nil { + return err } defer db.Close() @@ -46,7 +71,7 @@ func (cmd *ShareUpdateCmd) Run(logger *zap.Logger, globals Globals) error { return fmt.Errorf("failed to create node storage: %w", err) } - opSK, err := base64.StdEncoding.DecodeString(cmd.OperatorPrivateKey) + opSK, err := base64.StdEncoding.DecodeString(operatorPrivateKey) if err != nil { return err } @@ -67,66 +92,97 @@ func (cmd *ShareUpdateCmd) Run(logger *zap.Logger, globals Globals) error { if !found { return fmt.Errorf("operator data not found") } + if operatorData.ID != operatorID { + return fmt.Errorf("operator ID mismatch") + } logger.Info("operator data found", zap.Any("operator ID", operatorData.ID)) keyBytes := x509.MarshalPKCS1PrivateKey(rsaPriv) hashedKey, _ := rsaencryption.HashRsaKey(keyBytes) - networkConfig, err := networkconfig.GetNetworkConfigByName(cmd.NetworkName) - if err != nil { - return fmt.Errorf("failed to get network config: %w", err) - } keyManager, err := ekm.NewETHKeyManagerSigner(logger, db, networkConfig, false, hashedKey) if err != nil { return fmt.Errorf("failed to create key manager: %w", err) } - pkBytes, err := hex.DecodeString(cmd.ValidatorPubKey) - if err != nil { - return fmt.Errorf("failed to decode validator public key: %w", err) - } - - validatorShare := nodeStorage.Shares().Get(nil, pkBytes) - if validatorShare == nil { - return fmt.Errorf(fmt.Sprintf("validator share not found for %s", cmd.ValidatorPubKey)) - } - for i, op := range validatorShare.Committee { - if op.OperatorID == operatorData.ID { - var sk string - switch cmd.ValidatorPubKey { - case vpkLeader1: - sk = skLeader1 - case vpkLeader2: - sk = skLeader2 - default: - return fmt.Errorf("invalid validator public key") - } + for _, corruptedShare := range operatorCorruptedShares { + pkBytes, err := hex.DecodeString(corruptedShare.ValidatorPubKey) + if err != nil { + return fmt.Errorf("failed to decode validator public key: %w", err) + } - blsSK := &bls.SecretKey{} - if err = blsSK.SetHexString(sk); err != nil { - return fmt.Errorf("failed to set secret key: %w", err) - } + validatorShare := nodeStorage.Shares().Get(nil, pkBytes) + if validatorShare == nil { + return fmt.Errorf(fmt.Sprintf("validator share not found for %s", corruptedShare.ValidatorPubKey)) + } + if validatorShare.Metadata.BeaconMetadata.Index != corruptedShare.ValidatorIndex { + return fmt.Errorf("validator index mismatch for validator %s", corruptedShare.ValidatorPubKey) + } - if err = keyManager.AddShare(blsSK); err != nil { - return fmt.Errorf("failed to add share: %w", err) + var operatorFound bool + for i, op := range validatorShare.Committee { + if op.OperatorID == operatorData.ID { + operatorFound = true + + blsSK, blsPK := blskeygen.GenBLSKeyPair() + if err = keyManager.AddShare(blsSK); err != nil { + return fmt.Errorf("failed to add share: %w", err) + } + + preChangePK := validatorShare.SharePubKey + validatorShare.SharePubKey = blsPK.Serialize() + validatorShare.Share.Committee[i].PubKey = validatorShare.SharePubKey + if err = nodeStorage.Shares().Save(nil, validatorShare); err != nil { + return fmt.Errorf("failed to save share: %w", err) + } + + logger.Info("validator share was updated successfully", + zap.String("validator pub key", hex.EncodeToString(validatorShare.ValidatorPubKey)), + zap.String("BEFORE: share pub key", hex.EncodeToString(preChangePK)), + zap.String("AFTER: share pub key", hex.EncodeToString(validatorShare.SharePubKey)), + ) } + } + if !operatorFound { + return fmt.Errorf("operator %d not found in corrupted share", operatorData.ID) + } + } - preChangePK := validatorShare.SharePubKey - validatorShare.SharePubKey = blsSK.GetPublicKey().Serialize() - validatorShare.Share.Committee[i].PubKey = validatorShare.SharePubKey - if err = nodeStorage.Shares().Save(nil, validatorShare); err != nil { - return fmt.Errorf("failed to save share: %w", err) - } + return nil +} - logger.Info("validator share was updated successfully", - zap.String("validator pub key", hex.EncodeToString(validatorShare.ValidatorPubKey)), - zap.String("BEFORE: share pub key", hex.EncodeToString(preChangePK)), - zap.String("AFTER: share pub key", hex.EncodeToString(validatorShare.SharePubKey)), - ) - return nil - } +func openDB(logger *zap.Logger, dbPath string) (*kv.BadgerDB, error) { + db, err := kv.New(logger, basedb.Options{Path: dbPath}) + if err != nil { + return nil, fmt.Errorf("failed to open db: %w", err) + } + return db, nil +} + +func readOperatorPrivateKeyFromFile(filePath string) (string, error) { + var config ShareUpdateCmd + + data, err := os.ReadFile(filePath) + if err != nil { + return "", fmt.Errorf("failed to read file: %s, error: %w", filePath, err) + } + + if err = yaml.Unmarshal(data, &config); err != nil { + return "", fmt.Errorf("failed to unmarshal YAML: %w", err) + } + + return config.OperatorPrivateKey, nil +} + +// buildOperatorCorruptedSharesMap takes a slice of CorruptedShare and returns a map +// where each key is an OperatorID and the value is a slice of CorruptedShares associated with that OperatorID. +func buildOperatorCorruptedSharesMap(corruptedShares []*logs_catcher.CorruptedShare) map[types.OperatorID][]*logs_catcher.CorruptedShare { + operatorSharesMap := make(map[types.OperatorID][]*logs_catcher.CorruptedShare) + + for _, share := range corruptedShares { + operatorSharesMap[share.OperatorID] = append(operatorSharesMap[share.OperatorID], share) } - return fmt.Errorf("operator not found in validator share") + return operatorSharesMap } diff --git a/e2e/docker-compose.yml b/e2e/docker-compose.yml index 451da16040..92dba0415b 100644 --- a/e2e/docker-compose.yml +++ b/e2e/docker-compose.yml @@ -43,6 +43,7 @@ services: networks: - blox-docker volumes: + - ${PWD}/validators.json:/app/validators.json - /var/run/docker.sock:/var/run/docker.sock share_update: @@ -51,10 +52,16 @@ services: dockerfile: Dockerfile image: share_update:latest command: share-update - environment: - - NETWORK=holesky-e2e volumes: + - ${PWD}/validators.json:/app/validators.json + - ssv-node-1-data:/ssv-node-1-data - ssv-node-2-data:/ssv-node-2-data + - ssv-node-3-data:/ssv-node-3-data + - ssv-node-4-data:/ssv-node-4-data + - ${PWD}/config/share1.yaml:/tconfig/share1.yaml + - ${PWD}/config/share2.yaml:/tconfig/share2.yaml + - ${PWD}/config/share3.yaml:/tconfig/share3.yaml + - ${PWD}/config/share4.yaml:/tconfig/share4.yaml networks: - blox-docker diff --git a/e2e/logs_catcher/matcher.go b/e2e/logs_catcher/matcher.go index 1df06fdb04..31bca00139 100644 --- a/e2e/logs_catcher/matcher.go +++ b/e2e/logs_catcher/matcher.go @@ -72,9 +72,8 @@ func StartCondition(pctx context.Context, logger *zap.Logger, condition []string }() // TODO: either apply logs collection on each container or fan in the containers to one log stream err := docker.StreamDockerLogs(ctx, cli, targetContainer, ch) - if !errors.Is(err, context.Canceled) { + if err != nil && !errors.Is(err, context.Canceled) { logger.Error("Log streaming stopped with err ", zap.Error(err)) - cancel() return conditionLog, err } return conditionLog, nil diff --git a/e2e/logs_catcher/matcher_bls.go b/e2e/logs_catcher/matcher_bls.go index e1dcc2e192..a64b7f1977 100644 --- a/e2e/logs_catcher/matcher_bls.go +++ b/e2e/logs_catcher/matcher_bls.go @@ -50,21 +50,22 @@ type logCondition struct { } type CorruptedShare struct { - OperatorID types.OperatorID - ValidatorPubKey string - ValidatorIndex string + ValidatorIndex phase0.ValidatorIndex `json:"validator_index"` + ValidatorPubKey string `json:"validator_pub_key"` + OperatorID types.OperatorID `json:"operator_id"` } -func VerifyBLSSignature(pctx context.Context, logger *zap.Logger, cli DockerCLI, share CorruptedShare) error { - startctx, startc := context.WithTimeout(pctx, time.Minute*6*4) // wait max 4 epochs // TODO: dynamic wait based on leader? +func VerifyBLSSignature(pctx context.Context, logger *zap.Logger, cli DockerCLI, share *CorruptedShare) error { + startctx, startc := context.WithTimeout(pctx, time.Second*12*35) // wait max 35 slots defer startc() - conditionLog, err := StartCondition(startctx, logger, []string{gotDutiesSuccess, share.ValidatorIndex}, targetContainer, cli) + validatorIndex := fmt.Sprintf("v%d", share.ValidatorIndex) + conditionLog, err := StartCondition(startctx, logger, []string{gotDutiesSuccess, validatorIndex}, targetContainer, cli) if err != nil { return fmt.Errorf("failed to start condition: %w", err) } - dutyID, dutySlot, err := ParseAndExtractDutyInfo(conditionLog, share.ValidatorIndex) + dutyID, dutySlot, err := ParseAndExtractDutyInfo(conditionLog, validatorIndex) if err != nil { return fmt.Errorf("failed to parse and extract duty info: %w", err) } diff --git a/e2e/run.sh b/e2e/run.sh index c1efb10403..ac072b19ec 100755 --- a/e2e/run.sh +++ b/e2e/run.sh @@ -10,16 +10,10 @@ docker compose run --build logs_catcher logs-catcher --mode Slashing docker compose down # Step 4. Run share_update for non leader -docker compose run --build share_update share-update --validator-pub-key "8c5801d7a18e27fae47dfdd99c0ac67fbc6a5a56bb1fc52d0309626d805861e04eaaf67948c18ad50c96d63e44328ab0" --db-path "/ssv-node-2-data/db" --operator-private-key "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBd291VzR1SFRSMUQrdnYvYUU0Q09JeFQ1T0x5SGIwR0dieE01MDhQci82aW1XakRFCmxUUWR5Z2ZKblFld05Vb2FzdmthNEYzU2NxaTZTVGZDUG00a1V1RkY5YllsdXl3Q1ZKcUlpdjNVMW5acmlIbVQKTVRWNEpxaWxxVktIeU9HYlJKZUErQXdNZGRUR1pKTHRjenRXRTY4SUlzWkcwN1ZQQnpjQlJPdXVCWDNtQzNoSApjcVdjbzRFRlV0RHZGbXNKbEo2ZHB6SzYzcWREaFNIUXVWak5UbnhmRHpEV1BqK2RkMERzSWh6NCtDc3pEMzVCCnFFQ293a0REMCtiaXhkWEF5NTZsVi9JcUgxc3RCclEwQ2JnczJSbzlLbEVmc3VLbTNWdlFyejVQanhaUU9kc2cKMXhLS3JsZU8vQUw0T2lkeWV1aXBVM3IxQy90Yk9USjF1S3hSS1FJREFRQUJBb0lCQVFDSzlSKzZRT2tqaUhQZApRMnlsLzI0SEd1VUVwSXpzWjlZNUluZHNqZ1hVbjhicXB1alRWZDF0UC9DL0xBMnRrcGZOZkdhNUdlckdvVVFtCkppQ2xiUkNlN20rRkdTeU1LOXdpU0JyOWhGN3hMTGFVVFpwWVRNUGNnUnVLL1BzbC9oZGtmLzdMcmZkOGRwV2EKb3VQZUtlVEt2SHZJTXUzR0xEd2RnQ2wwN0E1cHRvdEh5WnpnckZuUlhpb1hRdmVqdnphYTJ2RDNKVWJKRk5QQQpsczZhejRqZWMrV2pyTnBQRnh5SWJHYzBNb2NZRVZVVC9CTlhZQmliNXc4M21kczJkM2x2RWpNNkJ2eWhBWGRTCkV2dGIyTTAwK0hUdzJOTlpjMXA3QXptUmZabG1wRHZmYVZCR0gwcTE4Q1R3eXZ0Q1JqZmkxWjNRZTFROTZCa3UKVFFFS3B3emRBb0dCQU5PaUgrcnlZWWxvKytTVzRRTlFKZytLQVh5Y0hJNzJtbTlkaTZwcElPbGQyc0FvaWM4UQpRbUV3VkhEUlZiMGRJNEdRYXlXeERYcGRTMFkrcWREV2JWTlN4YnY1ZFFKRTE1b0FKbm9sNWpqZ05la2RzVFdoCkFoU1pCb1ZXN2djc0ExVGJSa0VnamRIUzFTQmRoT3g3Wm5TV3BiT1BaMmttcXA4bGk3TStpV0kzQW9HQkFPdFUKWTZsbGNoZW1IODROOG02RXhxRU5nbDhJSERuUkxvUjNhc0R3dDBWOHJYbi85ditXMmVTRmtiZlRGRkNnMkZ3dQpiazRmZkhhV2g2dkNCYXdRNnI2RVJnMENEZGNTNzErZkU2ai9hNWZiWlNGR2V2b2J1bWtTN0pkSlNqYUdTNU5oCjFaN253YVU3OFErbDlTd20zeXJ3RitKYlN4bWM2dU9EL0NuL2RiZWZBb0dCQUx2d3hoZUhtRWJIREtzN3NpZVgKRGJYUEFQTUFUL3hGMDNBQ3l2MVN6djl2Y2N3a00vM0dtcXhrbHhoNVRvTGJWYVRCOCtWTkRvTVVScnppK1R1VQpzUkhGK0FPdXpOSnZBR2lxcVlEZ0YwdDdFV1VzRVN0bkNNbngrM0IrZW5PMENtRlpPVktzN2tUZnpwVW5kOXZxCjJsbS9UdmZlNmg3ZlQ3WjFTVktzdnFTUkFvR0FBYUJxcy9BTWt0ZEdId0Yvckgza2RaYUhVU3JZTHhvZ0RUQmEKSDQxS1p3T09tMnBHaGN2QUk5RThpWjIrNVRQSGF4T3pGWDBvT2hXZVNIU2wzMk9haThpVVIyQzlRY0JTd1VGegpQRmJQb3BRVXBkODcyR0M2c0NFK1cybFpSdmswcW9jaGwrQ1lPUkVxQUdhd1JDYmNvZ3BZeitxN29TaXhndk1WCm1pQzI2cGNDZ1lFQWpGejZVczhzczFPTmp1VEJ0MVozZFZXT0d4aVBSd1l2VTd4RWhJcWgzNUFZdWY4TWVSTzMKNDdwcThSc2Q0TnZiWnE0NE1JTmtZVXFsdUY4dmZCWE1oYWVURGtLNmhpSWo1TGNZOUNEbndtRFJ6a2kyTU9sMQo3UkdpUFhYNE05NVVUeEJwME5MZC9sTDdETVAxTUpMU2F0VmhHUEpmODZ0ci9kYk9NbFgrOHh3PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=" - -# Step 5. Run share_update for leader -docker compose run --build share_update share-update --validator-pub-key "a238aa8e3bd1890ac5def81e1a693a7658da491ac087d92cee870ab4d42998a184957321d70cbd42f9d38982dd9a928c" --db-path "/ssv-node-2-data/db" --operator-private-key "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBd291VzR1SFRSMUQrdnYvYUU0Q09JeFQ1T0x5SGIwR0dieE01MDhQci82aW1XakRFCmxUUWR5Z2ZKblFld05Vb2FzdmthNEYzU2NxaTZTVGZDUG00a1V1RkY5YllsdXl3Q1ZKcUlpdjNVMW5acmlIbVQKTVRWNEpxaWxxVktIeU9HYlJKZUErQXdNZGRUR1pKTHRjenRXRTY4SUlzWkcwN1ZQQnpjQlJPdXVCWDNtQzNoSApjcVdjbzRFRlV0RHZGbXNKbEo2ZHB6SzYzcWREaFNIUXVWak5UbnhmRHpEV1BqK2RkMERzSWh6NCtDc3pEMzVCCnFFQ293a0REMCtiaXhkWEF5NTZsVi9JcUgxc3RCclEwQ2JnczJSbzlLbEVmc3VLbTNWdlFyejVQanhaUU9kc2cKMXhLS3JsZU8vQUw0T2lkeWV1aXBVM3IxQy90Yk9USjF1S3hSS1FJREFRQUJBb0lCQVFDSzlSKzZRT2tqaUhQZApRMnlsLzI0SEd1VUVwSXpzWjlZNUluZHNqZ1hVbjhicXB1alRWZDF0UC9DL0xBMnRrcGZOZkdhNUdlckdvVVFtCkppQ2xiUkNlN20rRkdTeU1LOXdpU0JyOWhGN3hMTGFVVFpwWVRNUGNnUnVLL1BzbC9oZGtmLzdMcmZkOGRwV2EKb3VQZUtlVEt2SHZJTXUzR0xEd2RnQ2wwN0E1cHRvdEh5WnpnckZuUlhpb1hRdmVqdnphYTJ2RDNKVWJKRk5QQQpsczZhejRqZWMrV2pyTnBQRnh5SWJHYzBNb2NZRVZVVC9CTlhZQmliNXc4M21kczJkM2x2RWpNNkJ2eWhBWGRTCkV2dGIyTTAwK0hUdzJOTlpjMXA3QXptUmZabG1wRHZmYVZCR0gwcTE4Q1R3eXZ0Q1JqZmkxWjNRZTFROTZCa3UKVFFFS3B3emRBb0dCQU5PaUgrcnlZWWxvKytTVzRRTlFKZytLQVh5Y0hJNzJtbTlkaTZwcElPbGQyc0FvaWM4UQpRbUV3VkhEUlZiMGRJNEdRYXlXeERYcGRTMFkrcWREV2JWTlN4YnY1ZFFKRTE1b0FKbm9sNWpqZ05la2RzVFdoCkFoU1pCb1ZXN2djc0ExVGJSa0VnamRIUzFTQmRoT3g3Wm5TV3BiT1BaMmttcXA4bGk3TStpV0kzQW9HQkFPdFUKWTZsbGNoZW1IODROOG02RXhxRU5nbDhJSERuUkxvUjNhc0R3dDBWOHJYbi85ditXMmVTRmtiZlRGRkNnMkZ3dQpiazRmZkhhV2g2dkNCYXdRNnI2RVJnMENEZGNTNzErZkU2ai9hNWZiWlNGR2V2b2J1bWtTN0pkSlNqYUdTNU5oCjFaN253YVU3OFErbDlTd20zeXJ3RitKYlN4bWM2dU9EL0NuL2RiZWZBb0dCQUx2d3hoZUhtRWJIREtzN3NpZVgKRGJYUEFQTUFUL3hGMDNBQ3l2MVN6djl2Y2N3a00vM0dtcXhrbHhoNVRvTGJWYVRCOCtWTkRvTVVScnppK1R1VQpzUkhGK0FPdXpOSnZBR2lxcVlEZ0YwdDdFV1VzRVN0bkNNbngrM0IrZW5PMENtRlpPVktzN2tUZnpwVW5kOXZxCjJsbS9UdmZlNmg3ZlQ3WjFTVktzdnFTUkFvR0FBYUJxcy9BTWt0ZEdId0Yvckgza2RaYUhVU3JZTHhvZ0RUQmEKSDQxS1p3T09tMnBHaGN2QUk5RThpWjIrNVRQSGF4T3pGWDBvT2hXZVNIU2wzMk9haThpVVIyQzlRY0JTd1VGegpQRmJQb3BRVXBkODcyR0M2c0NFK1cybFpSdmswcW9jaGwrQ1lPUkVxQUdhd1JDYmNvZ3BZeitxN29TaXhndk1WCm1pQzI2cGNDZ1lFQWpGejZVczhzczFPTmp1VEJ0MVozZFZXT0d4aVBSd1l2VTd4RWhJcWgzNUFZdWY4TWVSTzMKNDdwcThSc2Q0TnZiWnE0NE1JTmtZVXFsdUY4dmZCWE1oYWVURGtLNmhpSWo1TGNZOUNEbndtRFJ6a2kyTU9sMQo3UkdpUFhYNE05NVVUeEJwME5MZC9sTDdETVAxTUpMU2F0VmhHUEpmODZ0ci9kYk9NbFgrOHh3PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=" +docker compose run --build share_update share-update # Step 6: Start the beacon_proxy and ssv-nodes again docker compose up -d beacon_proxy ssv-node-1 ssv-node-2 ssv-node-3 ssv-node-4 # Step 7: Run logs_catcher in Mode BlsVerification for non leader -docker compose run --build logs_catcher logs-catcher --mode BlsVerification --leader 1 - -# Step 8: Run logs_catcher in Mode BlsVerification for leader -docker compose run --build logs_catcher logs-catcher --mode BlsVerification --leader 2 +docker compose run --build logs_catcher logs-catcher --mode BlsVerification diff --git a/e2e/validators.json b/e2e/validators.json index 42fa885139..707e323982 100644 --- a/e2e/validators.json +++ b/e2e/validators.json @@ -1,32 +1,49 @@ - { - "1476356": "happy", - "1476357": "happy", - "1476358": "happy", - "1476359": "happy", - "1476360": "happy", - "1476361": "happy", - "1476362": "happy", - "1476363": "happy", - "1476364": "happy", - "1476365": "happy", - "1476366": "happy", - "1476367": "happy", - "1476368": "happy", - "1476369": "happy", - "1476370": "happy", - "1476371": "happy", - "1476372": "happy", - "1476373": "happy", - "1476374": "happy", - "1476375": "happy", - "1476376": "happy", - "1476377": "happy", - "1476378": "happy", - "1476379": "happy", - "1476380": "happy", - "1476381": "happy", - "1476382": "happy", - "1476383": "happy", - "1476384": "happy", - "1476385": "happy" +{ + "beacon_proxy": + { + "1476356": "happy", + "1476357": "happy", + "1476358": "happy", + "1476359": "happy", + "1476360": "happy", + "1476361": "happy", + "1476362": "happy", + "1476363": "happy", + "1476364": "happy", + "1476365": "happy", + "1476366": "happy", + "1476367": "happy", + "1476368": "happy", + "1476369": "happy", + "1476370": "happy", + "1476371": "happy", + "1476372": "happy", + "1476373": "happy", + "1476374": "happy", + "1476375": "happy", + "1476376": "happy", + "1476377": "happy", + "1476378": "happy", + "1476379": "happy", + "1476380": "happy", + "1476381": "happy", + "1476382": "happy", + "1476383": "happy", + "1476384": "happy", + "1476385": "happy" + }, + "bls_verification": [ + { + "validator_index": 1476356, + "validator_pub_key": "8c5801d7a18e27fae47dfdd99c0ac67fbc6a5a56bb1fc52d0309626d805861e04eaaf67948c18ad50c96d63e44328ab0", + "operator_id": 2, + "leader": 1 + }, + { + "validator_index": 1476357, + "validator_pub_key": "a238aa8e3bd1890ac5def81e1a693a7658da491ac087d92cee870ab4d42998a184957321d70cbd42f9d38982dd9a928c", + "operator_id": 2, + "leader": 2 + } + ] } \ No newline at end of file