diff --git a/.golangci.yaml b/.golangci.yaml index 3ac2ff0b6f..bb40568a9a 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -82,10 +82,6 @@ output: # all available settings of specific linters linters-settings: - gosec: - # TODO: fix all issues with int overflow and return this rule back - excludes: - - G115 dogsled: # checks assignments with too many blank identifiers; default is 2 max-blank-identifiers: 2 diff --git a/api/handling.go b/api/handling.go index 218527f723..3344986028 100644 --- a/api/handling.go +++ b/api/handling.go @@ -18,12 +18,18 @@ type HandlerFunc func(http.ResponseWriter, *http.Request) error func Handler(h HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if err := h(w, r); err != nil { - //nolint:all + //nolint:errorlint + // errors.As would be incorrect here since a renderer.Renderer + // wrapped inside another error should error, not render. switch e := err.(type) { case render.Renderer: - render.Render(w, r, e) + if err := render.Render(w, r, e); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } default: - render.Render(w, r, Error(err)) + if err := render.Render(w, r, Error(err)); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } } } } diff --git a/beacon/goclient/goclient.go b/beacon/goclient/goclient.go index 6d3fd3c617..b631a09e36 100644 --- a/beacon/goclient/goclient.go +++ b/beacon/goclient/goclient.go @@ -23,6 +23,7 @@ import ( operatordatastore "github.com/ssvlabs/ssv/operator/datastore" "github.com/ssvlabs/ssv/operator/slotticker" beaconprotocol "github.com/ssvlabs/ssv/protocol/v2/blockchain/beacon" + "github.com/ssvlabs/ssv/utils/casts" ) const ( @@ -263,8 +264,8 @@ func (gc *GoClient) GetBeaconNetwork() spectypes.BeaconNetwork { // SlotStartTime returns the start time in terms of its unix epoch // value. func (gc *GoClient) slotStartTime(slot phase0.Slot) time.Time { - duration := time.Second * time.Duration(uint64(slot)*uint64(gc.network.SlotDurationSec().Seconds())) - startTime := time.Unix(int64(gc.network.MinGenesisTime()), 0).Add(duration) + duration := time.Second * casts.DurationFromUint64(uint64(slot)*uint64(gc.network.SlotDurationSec().Seconds())) + startTime := time.Unix(gc.network.MinGenesisTime(), 0).Add(duration) return startTime } diff --git a/cli/operator/node.go b/cli/operator/node.go index 98bd58e065..fa94d113b3 100644 --- a/cli/operator/node.go +++ b/cli/operator/node.go @@ -438,6 +438,7 @@ func validateConfig(nodeStorage operatorstorage.Storage, networkName string, usi return fmt.Errorf("incompatible config change: %w", err) } } else { + if err := nodeStorage.SaveConfig(nil, currentConfig); err != nil { return fmt.Errorf("failed to store config: %w", err) } diff --git a/cli/threshold.go b/cli/threshold.go index 254898bd5b..a690a3f601 100644 --- a/cli/threshold.go +++ b/cli/threshold.go @@ -35,8 +35,8 @@ var createThresholdCmd = &cobra.Command{ logger.Fatal("failed to get keys count flag value", zap.Error(err)) } - if !ssvtypes.ValidCommitteeSize(int(keysCount)) { - logger.Fatal("invalid keys count", zap.Int("keysCount", int(keysCount))) + if !ssvtypes.ValidCommitteeSize(keysCount) { + logger.Fatal("invalid keys count", zap.Uint64("keysCount", keysCount)) } baseKey := &bls.SecretKey{} @@ -47,7 +47,7 @@ var createThresholdCmd = &cobra.Command{ // https://github.com/ethereum/eth2-ssv/issues/22 // currently support 4, 7, 10, 13 nodes threshold 3f+1. need to align based open the issue to // support k(2f+1) and n (3f+1) and allow to pass it as flag - quorum, _ := ssvtypes.ComputeQuorumAndPartialQuorum(int(keysCount)) + quorum, _ := ssvtypes.ComputeQuorumAndPartialQuorum(keysCount) privKeys, err := threshold.Create(baseKey.Serialize(), quorum, keysCount) if err != nil { logger.Fatal("failed to turn a private key into a threshold key", zap.Error(err)) diff --git a/eth/eventhandler/validation.go b/eth/eventhandler/validation.go index 303ec9a926..bdfbdb0823 100644 --- a/eth/eventhandler/validation.go +++ b/eth/eventhandler/validation.go @@ -25,7 +25,7 @@ func (eh *EventHandler) validateOperators(txn basedb.Txn, operators []uint64) er return fmt.Errorf("no operators") } - if !ssvtypes.ValidCommitteeSize(len(operators)) { + if !ssvtypes.ValidCommitteeSize(uint64(len(operators))) { return fmt.Errorf("given operator count (%d) cannot build a 3f+1 quorum", operatorCount) } diff --git a/exporter/api/query_handlers.go b/exporter/api/query_handlers.go index 8c91f5c731..b08d4bd9c6 100644 --- a/exporter/api/query_handlers.go +++ b/exporter/api/query_handlers.go @@ -12,6 +12,7 @@ import ( "github.com/ssvlabs/ssv/ibft/storage" "github.com/ssvlabs/ssv/logging/fields" "github.com/ssvlabs/ssv/protocol/v2/message" + "github.com/ssvlabs/ssv/utils/casts" ) const ( @@ -72,7 +73,7 @@ func HandleParticipantsQuery(logger *zap.Logger, qbftStorage *storage.QBFTStores nm.Msg = res return } - runnerRole := convert.RunnerRole(beaconRole) + runnerRole := casts.BeaconRoleToConvertRole(beaconRole) roleStorage := qbftStorage.Get(runnerRole) if roleStorage == nil { logger.Warn("role storage doesn't exist", fields.ExporterRole(runnerRole)) diff --git a/exporter/convert/message.go b/exporter/convert/message.go index c6fc712e7b..38a4724e31 100644 --- a/exporter/convert/message.go +++ b/exporter/convert/message.go @@ -3,6 +3,7 @@ package convert import ( "encoding/binary" "encoding/hex" + "math" spectypes "github.com/ssvlabs/ssv-spec/types" ) @@ -29,13 +30,24 @@ func (msg MessageID) GetDutyExecutorID() []byte { func (msg MessageID) GetRoleType() RunnerRole { roleByts := msg[roleTypeStartPos : roleTypeStartPos+roleTypeSize] - return RunnerRole(binary.LittleEndian.Uint32(roleByts)) + roleValue := binary.LittleEndian.Uint32(roleByts) + + // Sanitize RoleValue + if roleValue > math.MaxInt32 { + return spectypes.RoleUnknown + } + + return RunnerRole(roleValue) } func NewMsgID(domain spectypes.DomainType, dutyExecutorID []byte, role RunnerRole) MessageID { + // Sanitize role. If bad role, return an empty MessageID + roleValue := int32(role) + if roleValue < 0 { + return MessageID{} + } roleByts := make([]byte, 4) - binary.LittleEndian.PutUint32(roleByts, uint32(role)) - + binary.LittleEndian.PutUint32(roleByts, uint32(roleValue)) return newMessageID(domain[:], roleByts, dutyExecutorID) } diff --git a/integration/qbft/tests/test_duty.go b/integration/qbft/tests/test_duty.go index 8d40901366..cbc4458921 100644 --- a/integration/qbft/tests/test_duty.go +++ b/integration/qbft/tests/test_duty.go @@ -28,6 +28,7 @@ func createDuty(pk []byte, slot phase0.Slot, idx phase0.ValidatorIndex, role spe var beaconRole spectypes.BeaconRole switch role { case spectypes.RoleCommittee: + // #nosec G115 return spectestingutils.TestingCommitteeAttesterDuty(slot, []int{int(idx)}) case spectypes.RoleAggregator: testingDuty = spectestingutils.TestingAggregatorDuty diff --git a/message/validation/common_checks.go b/message/validation/common_checks.go index 7846bf2118..70e6918616 100644 --- a/message/validation/common_checks.go +++ b/message/validation/common_checks.go @@ -77,7 +77,7 @@ func (mv *messageValidator) validateDutyCount( return nil } -func (mv *messageValidator) dutyLimit(msgID spectypes.MessageID, slot phase0.Slot, validatorIndices []phase0.ValidatorIndex) (int, bool) { +func (mv *messageValidator) dutyLimit(msgID spectypes.MessageID, slot phase0.Slot, validatorIndices []phase0.ValidatorIndex) (uint64, bool) { switch msgID.GetRoleType() { case spectypes.RoleVoluntaryExit: pk := phase0.BLSPubKey{} @@ -89,8 +89,8 @@ func (mv *messageValidator) dutyLimit(msgID spectypes.MessageID, slot phase0.Slo return 2, true case spectypes.RoleCommittee: - validatorIndexCount := len(validatorIndices) - slotsPerEpoch := int(mv.netCfg.Beacon.SlotsPerEpoch()) + validatorIndexCount := uint64(len(validatorIndices)) + slotsPerEpoch := mv.netCfg.Beacon.SlotsPerEpoch() // Skip duty search if validators * 2 exceeds slots per epoch, // as the maximum duties per epoch is capped at the number of slots. diff --git a/message/validation/consensus_state.go b/message/validation/consensus_state.go index 4c9ba16f3d..f5d4b2c121 100644 --- a/message/validation/consensus_state.go +++ b/message/validation/consensus_state.go @@ -36,8 +36,8 @@ type OperatorState struct { state []*SignerState // the slice index is slot % storedSlotCount maxSlot phase0.Slot maxEpoch phase0.Epoch - lastEpochDuties int - prevEpochDuties int + lastEpochDuties uint64 + prevEpochDuties uint64 } func newOperatorState(size phase0.Slot) *OperatorState { @@ -50,7 +50,7 @@ func (os *OperatorState) Get(slot phase0.Slot) *SignerState { os.mu.RLock() defer os.mu.RUnlock() - s := os.state[int(slot)%len(os.state)] + s := os.state[(uint64(slot) % uint64(len(os.state)))] if s == nil || s.Slot != slot { return nil } @@ -62,7 +62,7 @@ func (os *OperatorState) Set(slot phase0.Slot, epoch phase0.Epoch, state *Signer os.mu.Lock() defer os.mu.Unlock() - os.state[int(slot)%len(os.state)] = state + os.state[uint64(slot)%uint64(len(os.state))] = state if slot > os.maxSlot { os.maxSlot = slot } @@ -82,7 +82,7 @@ func (os *OperatorState) MaxSlot() phase0.Slot { return os.maxSlot } -func (os *OperatorState) DutyCount(epoch phase0.Epoch) int { +func (os *OperatorState) DutyCount(epoch phase0.Epoch) uint64 { os.mu.RLock() defer os.mu.RUnlock() diff --git a/message/validation/consensus_state_test.go b/message/validation/consensus_state_test.go index e244588901..e8008fd804 100644 --- a/message/validation/consensus_state_test.go +++ b/message/validation/consensus_state_test.go @@ -62,8 +62,8 @@ func TestOperatorState(t *testing.T) { os.Set(slot, epoch, signerState) - require.Equal(t, os.DutyCount(epoch), 1) - require.Equal(t, os.DutyCount(epoch-1), 0) + require.Equal(t, os.DutyCount(epoch), uint64(1)) + require.Equal(t, os.DutyCount(epoch-1), uint64(0)) slot2 := phase0.Slot(6) epoch2 := phase0.Epoch(2) @@ -71,9 +71,9 @@ func TestOperatorState(t *testing.T) { os.Set(slot2, epoch2, signerState2) - require.Equal(t, os.DutyCount(epoch2), 1) - require.Equal(t, os.DutyCount(epoch), 1) - require.Equal(t, os.DutyCount(epoch-1), 0) + require.Equal(t, os.DutyCount(epoch2), uint64(1)) + require.Equal(t, os.DutyCount(epoch), uint64(1)) + require.Equal(t, os.DutyCount(epoch-1), uint64(0)) }) t.Run("TestIncrementLastEpochDuties", func(t *testing.T) { @@ -85,12 +85,12 @@ func TestOperatorState(t *testing.T) { signerState := &SignerState{Slot: slot} os.Set(slot, epoch, signerState) - require.Equal(t, os.DutyCount(epoch), 1) + require.Equal(t, os.DutyCount(epoch), uint64(1)) slot2 := phase0.Slot(6) signerState2 := &SignerState{Slot: slot2} os.Set(slot2, epoch, signerState2) - require.Equal(t, os.DutyCount(epoch), 2) + require.Equal(t, os.DutyCount(epoch), uint64(2)) }) } diff --git a/message/validation/consensus_validation.go b/message/validation/consensus_validation.go index ce34d2c89b..f3e9db31f2 100644 --- a/message/validation/consensus_validation.go +++ b/message/validation/consensus_validation.go @@ -18,6 +18,7 @@ import ( "github.com/ssvlabs/ssv/protocol/v2/message" "github.com/ssvlabs/ssv/protocol/v2/qbft/roundtimer" ssvtypes "github.com/ssvlabs/ssv/protocol/v2/types" + "github.com/ssvlabs/ssv/utils/casts" ) func (mv *messageValidator) validateConsensusMessage( @@ -81,7 +82,7 @@ func (mv *messageValidator) validateConsensusMessageSemantics( committee []spectypes.OperatorID, ) error { signers := signedSSVMessage.OperatorIDs - quorumSize, _ := ssvtypes.ComputeQuorumAndPartialQuorum(len(committee)) + quorumSize, _ := ssvtypes.ComputeQuorumAndPartialQuorum(uint64(len(committee))) msgType := consensusMessage.MsgType if len(signers) > 1 { @@ -376,14 +377,22 @@ func (mv *messageValidator) maxRound(role spectypes.RunnerRole) (specqbft.Round, } } -func (mv *messageValidator) currentEstimatedRound(sinceSlotStart time.Duration) specqbft.Round { - if currentQuickRound := specqbft.FirstRound + specqbft.Round(sinceSlotStart/roundtimer.QuickTimeout); currentQuickRound <= roundtimer.QuickTimeoutThreshold { - return currentQuickRound +func (mv *messageValidator) currentEstimatedRound(sinceSlotStart time.Duration) (specqbft.Round, error) { + delta, err := casts.DurationToUint64(sinceSlotStart / roundtimer.QuickTimeout) + if err != nil { + return 0, fmt.Errorf("failed to convert time duration to uint64: %w", err) + } + if currentQuickRound := specqbft.FirstRound + specqbft.Round(delta); currentQuickRound <= roundtimer.QuickTimeoutThreshold { + return currentQuickRound, nil } sinceFirstSlowRound := sinceSlotStart - (time.Duration(roundtimer.QuickTimeoutThreshold) * roundtimer.QuickTimeout) - estimatedRound := roundtimer.QuickTimeoutThreshold + specqbft.FirstRound + specqbft.Round(sinceFirstSlowRound/roundtimer.SlowTimeout) - return estimatedRound + delta, err = casts.DurationToUint64(sinceFirstSlowRound / roundtimer.SlowTimeout) + if err != nil { + return 0, fmt.Errorf("failed to convert time duration to uint64: %w", err) + } + estimatedRound := roundtimer.QuickTimeoutThreshold + specqbft.FirstRound + specqbft.Round(delta) + return estimatedRound, nil } func (mv *messageValidator) validConsensusMsgType(msgType specqbft.MessageType) bool { @@ -407,7 +416,11 @@ func (mv *messageValidator) roundBelongsToAllowedSpread( estimatedRound := specqbft.FirstRound if receivedAt.After(slotStartTime) { sinceSlotStart = receivedAt.Sub(slotStartTime) - estimatedRound = mv.currentEstimatedRound(sinceSlotStart) + currentEstimatedRound, err := mv.currentEstimatedRound(sinceSlotStart) + if err != nil { + return err + } + estimatedRound = currentEstimatedRound } // TODO: lowestAllowed is not supported yet because first round is non-deterministic now @@ -427,12 +440,12 @@ func (mv *messageValidator) roundBelongsToAllowedSpread( } func (mv *messageValidator) roundRobinProposer(height specqbft.Height, round specqbft.Round, committee []spectypes.OperatorID) types.OperatorID { - firstRoundIndex := 0 + firstRoundIndex := uint64(0) if height != specqbft.FirstHeight { - firstRoundIndex += int(height) % len(committee) + firstRoundIndex += uint64(height) % uint64(len(committee)) } - index := (firstRoundIndex + int(round) - int(specqbft.FirstRound)) % len(committee) + index := (firstRoundIndex + uint64(round) - uint64(specqbft.FirstRound)) % uint64(len(committee)) return committee[index] } diff --git a/message/validation/consensus_validation_test.go b/message/validation/consensus_validation_test.go index 7207a53f74..b1edbb8a3d 100644 --- a/message/validation/consensus_validation_test.go +++ b/message/validation/consensus_validation_test.go @@ -98,7 +98,8 @@ func TestMessageValidator_currentEstimatedRound(t *testing.T) { tc := tc t.Run(tc.name, func(t *testing.T) { mv := &messageValidator{} - got := mv.currentEstimatedRound(tc.sinceSlotStart) + got, err := mv.currentEstimatedRound(tc.sinceSlotStart) + require.NoError(t, err) require.Equal(t, tc.want, got) }) } diff --git a/message/validation/genesis/consensus_validation.go b/message/validation/genesis/consensus_validation.go index 06a36799ac..ca0a0623f4 100644 --- a/message/validation/genesis/consensus_validation.go +++ b/message/validation/genesis/consensus_validation.go @@ -15,6 +15,7 @@ import ( "github.com/ssvlabs/ssv/protocol/v2/qbft/roundtimer" ssvtypes "github.com/ssvlabs/ssv/protocol/v2/types" + "github.com/ssvlabs/ssv/utils/casts" ) func (mv *messageValidator) validateConsensusMessage( @@ -81,7 +82,10 @@ func (mv *messageValidator) validateConsensusMessage( estimatedRound := genesisspecqbft.FirstRound if receivedAt.After(slotStartTime) { sinceSlotStart = receivedAt.Sub(slotStartTime) - estimatedRound = mv.currentEstimatedRound(sinceSlotStart) + estimatedRound, err = mv.currentEstimatedRound(sinceSlotStart) + if err != nil { + return consensusDescriptor, msgSlot, err + } } // TODO: lowestAllowed is not supported yet because first round is non-deterministic now @@ -350,14 +354,25 @@ func (mv *messageValidator) maxRound(role genesisspectypes.BeaconRole) (genesiss } } -func (mv *messageValidator) currentEstimatedRound(sinceSlotStart time.Duration) genesisspecqbft.Round { - if currentQuickRound := genesisspecqbft.FirstRound + genesisspecqbft.Round(sinceSlotStart/roundtimer.QuickTimeout); currentQuickRound <= genesisspecqbft.Round(roundtimer.QuickTimeoutThreshold) { - return currentQuickRound +func (mv *messageValidator) currentEstimatedRound(sinceSlotStart time.Duration) (genesisspecqbft.Round, error) { + // Quick rounds (<= QuickTimeoutThreshold) + quickRounds, err := casts.DurationToUint64(sinceSlotStart / roundtimer.QuickTimeout) + if err != nil { + return 0, fmt.Errorf("failed to convert time duration to uint64: %w", err) + } + currentQuickRound := genesisspecqbft.FirstRound + genesisspecqbft.Round(quickRounds) + if currentQuickRound <= genesisspecqbft.Round(roundtimer.QuickTimeoutThreshold) { + return currentQuickRound, nil } + // Slow rounds (> QuickTimeoutThreshold) sinceFirstSlowRound := sinceSlotStart - (time.Duration(genesisspecqbft.Round(roundtimer.QuickTimeoutThreshold)) * roundtimer.QuickTimeout) - estimatedRound := genesisspecqbft.Round(roundtimer.QuickTimeoutThreshold) + genesisspecqbft.FirstRound + genesisspecqbft.Round(sinceFirstSlowRound/roundtimer.SlowTimeout) - return estimatedRound + slowRounds, err := casts.DurationToUint64(sinceFirstSlowRound / roundtimer.SlowTimeout) + if err != nil { + return 0, fmt.Errorf("failed to convert time duration to uint64: %w", err) + } + currentSlowRound := genesisspecqbft.Round(roundtimer.QuickTimeoutThreshold) + genesisspecqbft.FirstRound + genesisspecqbft.Round(slowRounds) + return currentSlowRound, nil } func (mv *messageValidator) waitAfterSlotStart(role genesisspectypes.BeaconRole) (time.Duration, error) { @@ -416,7 +431,7 @@ func (mv *messageValidator) validConsensusSigners(share *ssvtypes.SSVShare, m *g e.got = len(m.Signers) return e - case !share.HasQuorum(len(m.Signers)) || len(m.Signers) > len(share.Committee): + case !share.HasQuorum(uint64(len(m.Signers))) || len(m.Signers) > len(share.Committee): e := ErrWrongSignersLength e.want = fmt.Sprintf("between %v and %v", share.Quorum(), len(share.Committee)) e.got = len(m.Signers) @@ -441,11 +456,11 @@ func (mv *messageValidator) validConsensusSigners(share *ssvtypes.SSVShare, m *g } func (mv *messageValidator) roundRobinProposer(height genesisspecqbft.Height, round genesisspecqbft.Round, share *ssvtypes.SSVShare) genesisspectypes.OperatorID { - firstRoundIndex := 0 + firstRoundIndex := uint64(0) if height != genesisspecqbft.FirstHeight { - firstRoundIndex += int(height) % len(share.Committee) + firstRoundIndex += uint64(height) % uint64(len(share.Committee)) } - index := (firstRoundIndex + int(round) - int(genesisspecqbft.FirstRound)) % len(share.Committee) + index := (firstRoundIndex + uint64(round) - uint64(genesisspecqbft.FirstRound)) % uint64(len(share.Committee)) return share.Committee[index].Signer } diff --git a/message/validation/genesis/consensus_validation_test.go b/message/validation/genesis/consensus_validation_test.go index 21293c6a0d..c88fc8d794 100644 --- a/message/validation/genesis/consensus_validation_test.go +++ b/message/validation/genesis/consensus_validation_test.go @@ -98,7 +98,8 @@ func TestMessageValidator_currentEstimatedRound(t *testing.T) { tc := tc t.Run(tc.name, func(t *testing.T) { mv := &messageValidator{} - got := mv.currentEstimatedRound(tc.sinceSlotStart) + got, err := mv.currentEstimatedRound(tc.sinceSlotStart) + require.NoError(t, err) require.Equal(t, tc.want, got) }) } diff --git a/message/validation/validation_test.go b/message/validation/validation_test.go index c8a2548cf2..8376cd8b25 100644 --- a/message/validation/validation_test.go +++ b/message/validation/validation_test.go @@ -1392,7 +1392,12 @@ func Test_ValidateSSVMessage(t *testing.T) { topicID := commons.CommitteeTopicID(committeeID)[0] sinceSlotStart := time.Duration(0) - for validator.currentEstimatedRound(sinceSlotStart) != round { + for { + currentRound, err := validator.currentEstimatedRound(sinceSlotStart) + require.NoError(t, err) + if currentRound == round { + break + } sinceSlotStart += roundtimer.QuickTimeout } diff --git a/migrations/migrations.go b/migrations/migrations.go index 521baa73e7..e9a34bc066 100644 --- a/migrations/migrations.go +++ b/migrations/migrations.go @@ -13,7 +13,6 @@ import ( "github.com/ssvlabs/ssv/ekm" operatorstorage "github.com/ssvlabs/ssv/operator/storage" "github.com/ssvlabs/ssv/protocol/v2/blockchain/beacon" - "github.com/ssvlabs/ssv/protocol/v2/blockchain/eth1" "github.com/ssvlabs/ssv/storage/basedb" ) @@ -59,15 +58,6 @@ type Options struct { Network beacon.Network } -// nolint -func (o Options) getRegistryStores(logger *zap.Logger) ([]eth1.RegistryStore, error) { - nodeStorage, err := o.nodeStorage(logger) - if err != nil { - return nil, err - } - return []eth1.RegistryStore{nodeStorage, o.signerStorage(logger)}, nil -} - // nolint func (o Options) nodeStorage(logger *zap.Logger) (operatorstorage.Storage, error) { return operatorstorage.NewNodeStorage(logger, o.Db) diff --git a/network/commons/common.go b/network/commons/common.go index f496c12e84..2a9036e9bf 100644 --- a/network/commons/common.go +++ b/network/commons/common.go @@ -4,6 +4,7 @@ import ( "encoding/binary" "encoding/hex" "fmt" + "math" "math/big" "strconv" "strings" @@ -27,6 +28,8 @@ const ( // SubnetsCount returns the subnet count for genesis SubnetsCount uint64 = 128 + UnknownSubnetId = math.MaxUint64 + // UnknownSubnet is used when a validator public key is invalid UnknownSubnet = "unknown" @@ -65,8 +68,8 @@ func DecodeGenesisSignedSSVMessage(encoded []byte) ([]byte, genesisspectypes.Ope } // SubnetTopicID returns the topic to use for the given subnet -func SubnetTopicID(subnet int) string { - if subnet < 0 { +func SubnetTopicID(subnet uint64) string { + if subnet == UnknownSubnetId { return UnknownSubnet } return fmt.Sprintf("%d", subnet) @@ -80,7 +83,7 @@ func ValidatorTopicID(pkByts []byte) []string { } func CommitteeTopicID(cid spectypes.CommitteeID) []string { - return []string{strconv.Itoa(CommitteeSubnet(cid))} + return []string{fmt.Sprintf("%d", CommitteeSubnet(cid))} } // GetTopicFullName returns the topic full name, including prefix @@ -94,18 +97,19 @@ func GetTopicBaseName(topicName string) string { } // ValidatorSubnet returns the subnet for the given validator -func ValidatorSubnet(validatorPKHex string) int { +func ValidatorSubnet(validatorPKHex string) uint64 { if len(validatorPKHex) < 10 { - return -1 + return UnknownSubnetId } val := hexToUint64(validatorPKHex[:10]) - return int(val % SubnetsCount) + + return val % SubnetsCount } // CommitteeSubnet returns the subnet for the given committee -func CommitteeSubnet(cid spectypes.CommitteeID) int { +func CommitteeSubnet(cid spectypes.CommitteeID) uint64 { subnet := new(big.Int).Mod(new(big.Int).SetBytes(cid[:]), new(big.Int).SetUint64(SubnetsCount)) - return int(subnet.Int64()) + return subnet.Uint64() } // MsgIDFunc is the function that maps a message to a msg_id @@ -132,7 +136,7 @@ func Subnets() int { // Topics returns the available topics for this fork. func Topics() []string { topics := make([]string, Subnets()) - for i := 0; i < Subnets(); i++ { + for i := uint64(0); i < SubnetsCount; i++ { topics[i] = GetTopicFullName(SubnetTopicID(i)) } return topics diff --git a/network/discovery/dv5_bootnode.go b/network/discovery/dv5_bootnode.go index c9f6766bb0..d4e619770f 100644 --- a/network/discovery/dv5_bootnode.go +++ b/network/discovery/dv5_bootnode.go @@ -14,7 +14,7 @@ import ( type BootnodeOptions struct { PrivateKey string `yaml:"PrivateKey" env:"BOOTNODE_NETWORK_KEY" env-description:"Bootnode private key (default will generate new)"` ExternalIP string `yaml:"ExternalIP" env:"BOOTNODE_EXTERNAL_IP" env-description:"Override boot node's IP' "` - Port int `yaml:"Port" env:"BOOTNODE_PORT" env-description:"Override boot node's port' "` + Port uint16 `yaml:"Port" env:"BOOTNODE_PORT" env-description:"Override boot node's port' "` } // Bootnode represents a bootnode used for tests diff --git a/network/discovery/dv5_routing.go b/network/discovery/dv5_routing.go index 2ffa08c0f1..0f69fe5d60 100644 --- a/network/discovery/dv5_routing.go +++ b/network/discovery/dv5_routing.go @@ -56,7 +56,7 @@ func (dvs *DiscV5Service) FindPeers(ctx context.Context, ns string, opt ...disco dvs.discover(ctx, func(e PeerEvent) { cn <- e.AddrInfo - }, time.Millisecond, dvs.ssvNodeFilter(logger), dvs.badNodeFilter(logger), dvs.subnetFilter(uint64(subnet))) + }, time.Millisecond, dvs.ssvNodeFilter(logger), dvs.badNodeFilter(logger), dvs.subnetFilter(subnet)) return cn, nil } diff --git a/network/discovery/dv5_service.go b/network/discovery/dv5_service.go index b7cd72754b..055ffbc0d0 100644 --- a/network/discovery/dv5_service.go +++ b/network/discovery/dv5_service.go @@ -209,7 +209,7 @@ func (dvs *DiscV5Service) initDiscV5Listener(logger *zap.Logger, discOpts *Optio dvs.bootnodes = dv5Cfg.Bootnodes logger.Debug("started discv5 listener (UDP)", fields.BindIP(bindIP), - zap.Int("UdpPort", opts.Port), fields.ENRLocalNode(localNode), fields.Domain(discOpts.DomainType.DomainType())) + zap.Uint16("UdpPort", opts.Port), fields.ENRLocalNode(localNode), fields.Domain(discOpts.DomainType.DomainType())) return nil } @@ -260,7 +260,7 @@ func (dvs *DiscV5Service) discover(ctx context.Context, handler HandleNewPeer, i } // RegisterSubnets adds the given subnets and publish the updated node record -func (dvs *DiscV5Service) RegisterSubnets(logger *zap.Logger, subnets ...int) (updated bool, err error) { +func (dvs *DiscV5Service) RegisterSubnets(logger *zap.Logger, subnets ...uint64) (updated bool, err error) { if len(subnets) == 0 { return false, nil } @@ -277,7 +277,7 @@ func (dvs *DiscV5Service) RegisterSubnets(logger *zap.Logger, subnets ...int) (u } // DeregisterSubnets removes the given subnets and publish the updated node record -func (dvs *DiscV5Service) DeregisterSubnets(logger *zap.Logger, subnets ...int) (updated bool, err error) { +func (dvs *DiscV5Service) DeregisterSubnets(logger *zap.Logger, subnets ...uint64) (updated bool, err error) { logger = logger.Named(logging.NameDiscoveryService) if len(subnets) == 0 { @@ -384,10 +384,10 @@ func (dvs *DiscV5Service) createLocalNode(logger *zap.Logger, discOpts *Options, } // newUDPListener creates a udp server -func newUDPListener(bindIP net.IP, port int, network string) (*net.UDPConn, error) { +func newUDPListener(bindIP net.IP, port uint16, network string) (*net.UDPConn, error) { udpAddr := &net.UDPAddr{ IP: bindIP, - Port: port, + Port: int(port), } conn, err := net.ListenUDP(network, udpAddr) if err != nil { diff --git a/network/discovery/enode.go b/network/discovery/enode.go index 811d125096..f31320a8d5 100644 --- a/network/discovery/enode.go +++ b/network/discovery/enode.go @@ -16,7 +16,7 @@ import ( ) // createLocalNode create a new enode.LocalNode instance -func createLocalNode(privKey *ecdsa.PrivateKey, storagePath string, ipAddr net.IP, udpPort, tcpPort int) (*enode.LocalNode, error) { +func createLocalNode(privKey *ecdsa.PrivateKey, storagePath string, ipAddr net.IP, udpPort, tcpPort uint16) (*enode.LocalNode, error) { db, err := enode.OpenDB(storagePath) if err != nil { return nil, errors.Wrap(err, "could not open node's peer database") @@ -27,7 +27,7 @@ func createLocalNode(privKey *ecdsa.PrivateKey, storagePath string, ipAddr net.I localNode.Set(enr.UDP(udpPort)) localNode.Set(enr.TCP(tcpPort)) localNode.SetFallbackIP(ipAddr) - localNode.SetFallbackUDP(udpPort) + localNode.SetFallbackUDP(int(udpPort)) localNode.Set(enr.WithEntry("ssv", true)) return localNode, nil @@ -92,7 +92,7 @@ func ToMultiAddr(node *enode.Node) (ma.Multiaddr, error) { if ip.To4() == nil && ip.To16() == nil { return nil, errors.Errorf("invalid ip address: %s", ipAddr) } - port := uint(node.TCP()) + port := node.TCP() var s string if ip.To4() != nil { s = fmt.Sprintf("/ip4/%s/%s/%d/p2p/%s", ipAddr, "tcp", port, id.String()) diff --git a/network/discovery/local_service.go b/network/discovery/local_service.go index 5ad0a94196..5127036828 100644 --- a/network/discovery/local_service.go +++ b/network/discovery/local_service.go @@ -94,13 +94,13 @@ func (md *localDiscovery) FindPeers(ctx context.Context, ns string, opt ...disco } // RegisterSubnets implements Service -func (md *localDiscovery) RegisterSubnets(logger *zap.Logger, subnets ...int) (updated bool, err error) { +func (md *localDiscovery) RegisterSubnets(logger *zap.Logger, subnets ...uint64) (updated bool, err error) { // TODO return false, nil } // DeregisterSubnets implements Service -func (md *localDiscovery) DeregisterSubnets(logger *zap.Logger, subnets ...int) (updated bool, err error) { +func (md *localDiscovery) DeregisterSubnets(logger *zap.Logger, subnets ...uint64) (updated bool, err error) { // TODO return false, nil } diff --git a/network/discovery/options.go b/network/discovery/options.go index 5cb359d231..da54032003 100644 --- a/network/discovery/options.go +++ b/network/discovery/options.go @@ -28,9 +28,9 @@ type DiscV5Options struct { // BindIP is the IP to bind to the UDP listener BindIP string // Port is the UDP port used by discv5 - Port int + Port uint16 // TCPPort is the TCP port exposed in the ENR - TCPPort int + TCPPort uint16 // NetworkKey is the private key used to create the peer.ID if the node NetworkKey *ecdsa.PrivateKey // Bootnodes is a list of bootstrapper nodes diff --git a/network/discovery/service.go b/network/discovery/service.go index 51d131f329..15c66fb449 100644 --- a/network/discovery/service.go +++ b/network/discovery/service.go @@ -49,8 +49,8 @@ type Options struct { type Service interface { discovery.Discovery io.Closer - RegisterSubnets(logger *zap.Logger, subnets ...int) (updated bool, err error) - DeregisterSubnets(logger *zap.Logger, subnets ...int) (updated bool, err error) + RegisterSubnets(logger *zap.Logger, subnets ...uint64) (updated bool, err error) + DeregisterSubnets(logger *zap.Logger, subnets ...uint64) (updated bool, err error) Bootstrap(logger *zap.Logger, handler HandleNewPeer) error PublishENR(logger *zap.Logger) } diff --git a/network/discovery/subnets.go b/network/discovery/subnets.go index 175120d598..dd8c26c555 100644 --- a/network/discovery/subnets.go +++ b/network/discovery/subnets.go @@ -15,7 +15,7 @@ var ( ) // nsToSubnet converts the given topic to subnet -func (dvs *DiscV5Service) nsToSubnet(ns string) (int, error) { +func (dvs *DiscV5Service) nsToSubnet(ns string) (uint64, error) { r, done := regPool.Get() defer done() @@ -29,11 +29,11 @@ func (dvs *DiscV5Service) nsToSubnet(ns string) (int, error) { return 0, err } - if val >= uint64(commons.Subnets()) { + if val >= commons.SubnetsCount { return 0, errValueOutOfRange } - return int(val), nil + return val, nil } // isSubnet checks if the given string is a subnet string diff --git a/network/discovery/subnets_test.go b/network/discovery/subnets_test.go index 69e79e8eea..cea742d908 100644 --- a/network/discovery/subnets_test.go +++ b/network/discovery/subnets_test.go @@ -10,7 +10,7 @@ func TestNsToSubnet(t *testing.T) { tests := []struct { name string ns string - expected int + expected uint64 expectedErr string isSubnet bool }{ diff --git a/network/p2p/config.go b/network/p2p/config.go index b6328ba364..c659b610ea 100644 --- a/network/p2p/config.go +++ b/network/p2p/config.go @@ -39,8 +39,8 @@ type Config struct { Discovery string `yaml:"Discovery" env:"P2P_DISCOVERY" env-description:"Discovery system to use" env-default:"discv5"` TrustedPeers []string `yaml:"TrustedPeers" env:"TRUSTED_PEERS" env-default:"" env-description:"List of peers to connect to."` - TCPPort int `yaml:"TcpPort" env:"TCP_PORT" env-default:"13001" env-description:"TCP port for p2p transport"` - UDPPort int `yaml:"UdpPort" env:"UDP_PORT" env-default:"12001" env-description:"UDP port for discovery"` + TCPPort uint16 `yaml:"TcpPort" env:"TCP_PORT" env-default:"13001" env-description:"TCP port for p2p transport"` + UDPPort uint16 `yaml:"UdpPort" env:"UDP_PORT" env-default:"12001" env-description:"UDP port for discovery"` HostAddress string `yaml:"HostAddress" env:"HOST_ADDRESS" env-description:"External ip node is exposed for discovery"` HostDNS string `yaml:"HostDNS" env:"HOST_DNS" env-description:"External DNS node is exposed for discovery"` diff --git a/network/p2p/p2p.go b/network/p2p/p2p.go index 4a412ca337..674ab65c94 100644 --- a/network/p2p/p2p.go +++ b/network/p2p/p2p.go @@ -377,18 +377,18 @@ func (n *p2pNetwork) UpdateSubnets(logger *zap.Logger) { n.activeSubnets = updatedSubnets // Compute the not yet registered subnets. - addedSubnets := make([]int, 0) + addedSubnets := make([]uint64, 0) for subnet, active := range updatedSubnets { if active == byte(1) && registeredSubnets[subnet] == byte(0) { - addedSubnets = append(addedSubnets, subnet) + addedSubnets = append(addedSubnets, uint64(subnet)) // #nosec G115 -- subnets has a constant max len of 128 } } // Compute the not anymore registered subnets. - removedSubnets := make([]int, 0) + removedSubnets := make([]uint64, 0) for subnet, active := range registeredSubnets { if active == byte(1) && updatedSubnets[subnet] == byte(0) { - removedSubnets = append(removedSubnets, subnet) + removedSubnets = append(removedSubnets, uint64(subnet)) // #nosec G115 -- subnets has a constant max len of 128 } } @@ -423,12 +423,12 @@ func (n *p2pNetwork) UpdateSubnets(logger *zap.Logger) { } // Unsubscribe from the removed subnets. - for _, subnet := range removedSubnets { - if err := n.unsubscribeSubnet(logger, uint(subnet)); err != nil { - logger.Debug("could not unsubscribe from subnet", zap.Int("subnet", subnet), zap.Error(err)) + for _, removedSubnet := range removedSubnets { + if err := n.unsubscribeSubnet(logger, removedSubnet); err != nil { + logger.Debug("could not unsubscribe from subnet", zap.Uint64("subnet", removedSubnet), zap.Error(err)) errs = errors.Join(errs, err) } else { - logger.Debug("unsubscribed from subnet", zap.Int("subnet", subnet)) + logger.Debug("unsubscribed from subnet", zap.Uint64("subnet", removedSubnet)) } } } diff --git a/network/p2p/p2p_genesis.go b/network/p2p/p2p_genesis.go index 7d6539e33a..eb042fd388 100644 --- a/network/p2p/p2p_genesis.go +++ b/network/p2p/p2p_genesis.go @@ -20,7 +20,7 @@ type GenesisP2P struct { func (p *GenesisP2P) Broadcast(message *genesisspectypes.SSVMessage) error { - zap.L().Debug("broadcasting genesis msg", fields.PubKey(message.MsgID.GetPubKey()), zap.Int("msg_type", int(message.MsgType))) + zap.L().Debug("broadcasting genesis msg", fields.PubKey(message.MsgID.GetPubKey()), zap.Uint64("msg_type", uint64(message.MsgType))) if !p.Network.isReady() { return p2pprotocol.ErrNetworkIsNotReady @@ -50,7 +50,7 @@ func (p *GenesisP2P) Broadcast(message *genesisspectypes.SSVMessage) error { for _, topic := range topics { p.Network.interfaceLogger.Debug("broadcasting msg", fields.PubKey(message.MsgID.GetPubKey()), - zap.Int("msg_type", int(message.MsgType)), + zap.Uint64("msg_type", uint64(message.MsgType)), fields.Topic(topic)) if err := p.Network.topicsCtrl.Broadcast(topic, encodedMsg, p.Network.cfg.RequestTimeout); err != nil { p.Network.interfaceLogger.Debug("could not broadcast msg", fields.PubKey(message.MsgID.GetPubKey()), zap.Error(err)) diff --git a/network/p2p/p2p_pubsub.go b/network/p2p/p2p_pubsub.go index 07a18544a4..68baf5126c 100644 --- a/network/p2p/p2p_pubsub.go +++ b/network/p2p/p2p_pubsub.go @@ -77,7 +77,7 @@ func (n *p2pNetwork) SubscribeAll(logger *zap.Logger) error { return p2pprotocol.ErrNetworkIsNotReady } n.fixedSubnets, _ = records.Subnets{}.FromString(records.AllSubnets) - for subnet := 0; subnet < commons.Subnets(); subnet++ { + for subnet := uint64(0); subnet < commons.SubnetsCount; subnet++ { err := n.topicsCtrl.Subscribe(logger, commons.SubnetTopicID(subnet)) if err != nil { return err @@ -100,7 +100,8 @@ func (n *p2pNetwork) SubscribeRandoms(logger *zap.Logger, numSubnets int) error randomSubnets := rand.New(rand.NewSource(time.Now().UnixNano())).Perm(commons.Subnets()) randomSubnets = randomSubnets[:numSubnets] for _, subnet := range randomSubnets { - err := n.topicsCtrl.Subscribe(logger, commons.SubnetTopicID(subnet)) + // #nosec G115 + err := n.topicsCtrl.Subscribe(logger, commons.SubnetTopicID(uint64(subnet))) // Perm slice is [0, n) if err != nil { return fmt.Errorf("could not subscribe to subnet %d: %w", subnet, err) } @@ -172,14 +173,14 @@ func (n *p2pNetwork) subscribeValidator(pk spectypes.ValidatorPK) error { return nil } -func (n *p2pNetwork) unsubscribeSubnet(logger *zap.Logger, subnet uint) error { +func (n *p2pNetwork) unsubscribeSubnet(logger *zap.Logger, subnet uint64) error { if !n.isReady() { return p2pprotocol.ErrNetworkIsNotReady } - if subnet >= uint(commons.Subnets()) { + if subnet >= commons.SubnetsCount { return fmt.Errorf("invalid subnet %d", subnet) } - if err := n.topicsCtrl.Unsubscribe(logger, commons.SubnetTopicID(int(subnet)), false); err != nil { + if err := n.topicsCtrl.Unsubscribe(logger, commons.SubnetTopicID(subnet), false); err != nil { return fmt.Errorf("could not unsubscribe from subnet %d: %w", subnet, err) } return nil diff --git a/network/p2p/p2p_setup.go b/network/p2p/p2p_setup.go index 65f2d72f71..0a4893a80c 100644 --- a/network/p2p/p2p_setup.go +++ b/network/p2p/p2p_setup.go @@ -57,8 +57,6 @@ func (n *p2pNetwork) Setup(logger *zap.Logger) error { return errors.New("could not setup network: in ready state") } - // set a seed for rand values - rand.Seed(time.Now().UnixNano()) // nolint: staticcheck logger.Info("configuring") if err := n.initCfg(); err != nil { diff --git a/network/p2p/p2p_validation_test.go b/network/p2p/p2p_validation_test.go index dd70113b24..69bd60175e 100644 --- a/network/p2p/p2p_validation_test.go +++ b/network/p2p/p2p_validation_test.go @@ -138,7 +138,7 @@ func TestP2pNetwork_MessageValidation(t *testing.T) { } // Create a VirtualNet with 4 nodes. - vNet = CreateVirtualNet(t, ctx, 4, shares, func(nodeIndex int) validation.MessageValidator { + vNet = CreateVirtualNet(t, ctx, 4, shares, func(nodeIndex uint64) validation.MessageValidator { return messageValidators[nodeIndex] }) @@ -338,7 +338,7 @@ func CreateVirtualNet( ctx context.Context, nodes int, shares []*ssvtypes.SSVShare, - messageValidatorProvider func(int) validation.MessageValidator, + messageValidatorProvider func(uint64) validation.MessageValidator, ) *VirtualNet { var doneSetup atomic.Bool vn := &VirtualNet{} diff --git a/network/p2p/test_utils.go b/network/p2p/test_utils.go index 9762911873..04e5bd0d59 100644 --- a/network/p2p/test_utils.go +++ b/network/p2p/test_utils.go @@ -131,7 +131,7 @@ func (mockSignatureVerifier) VerifySignature(operatorID spectypes.OperatorID, me } // NewTestP2pNetwork creates a new network.P2PNetwork instance -func (ln *LocalNet) NewTestP2pNetwork(ctx context.Context, nodeIndex int, keys testing.NodeKeys, logger *zap.Logger, options LocalNetOptions) (network.P2PNetwork, error) { +func (ln *LocalNet) NewTestP2pNetwork(ctx context.Context, nodeIndex uint64, keys testing.NodeKeys, logger *zap.Logger, options LocalNetOptions) (network.P2PNetwork, error) { operatorPubkey, err := keys.OperatorKey.Public().Base64() if err != nil { return nil, err @@ -190,7 +190,7 @@ func (ln *LocalNet) NewTestP2pNetwork(ctx context.Context, nodeIndex int, keys t cfg.Network = networkconfig.TestNetwork if options.TotalValidators > 0 { cfg.GetValidatorStats = func() (uint64, uint64, uint64, error) { - return uint64(options.TotalValidators), uint64(options.ActiveValidators), uint64(options.MyValidators), nil + return options.TotalValidators, options.ActiveValidators, options.MyValidators, nil } } @@ -222,7 +222,7 @@ func (ln *LocalNet) NewTestP2pNetwork(ctx context.Context, nodeIndex int, keys t cfg.PeerScoreInspectorInterval = options.PeerScoreInspectorInterval } - cfg.OperatorDataStore = operatordatastore.New(®istrystorage.OperatorData{ID: spectypes.OperatorID(nodeIndex + 1)}) + cfg.OperatorDataStore = operatordatastore.New(®istrystorage.OperatorData{ID: nodeIndex + 1}) mr := metricsreporter.New() p, err := New(logger, cfg, mr) @@ -237,11 +237,11 @@ func (ln *LocalNet) NewTestP2pNetwork(ctx context.Context, nodeIndex int, keys t } type LocalNetOptions struct { - MessageValidatorProvider func(int) validation.MessageValidator + MessageValidatorProvider func(uint64) validation.MessageValidator Nodes int MinConnected int UseDiscv5 bool - TotalValidators, ActiveValidators, MyValidators int + TotalValidators, ActiveValidators, MyValidators uint64 PeerScoreInspector func(selfPeer peer.ID, peerMap map[peer.ID]*pubsub.PeerScoreSnapshot) PeerScoreInspectorInterval time.Duration Shares []*ssvtypes.SSVShare @@ -256,7 +256,7 @@ func NewLocalNet(ctx context.Context, logger *zap.Logger, options LocalNetOption return nil, err } } - nodes, keys, err := testing.NewLocalTestnet(ctx, options.Nodes, func(pctx context.Context, nodeIndex int, keys testing.NodeKeys) network.P2PNetwork { + nodes, keys, err := testing.NewLocalTestnet(ctx, options.Nodes, func(pctx context.Context, nodeIndex uint64, keys testing.NodeKeys) network.P2PNetwork { logger := logger.Named(fmt.Sprintf("node-%d", nodeIndex)) p, err := ln.NewTestP2pNetwork(pctx, nodeIndex, keys, logger, options) if err != nil { @@ -274,7 +274,7 @@ func NewLocalNet(ctx context.Context, logger *zap.Logger, options LocalNetOption } // NewNetConfig creates a new config for tests -func NewNetConfig(keys testing.NodeKeys, operatorPubKeyHash string, bn *discovery.Bootnode, tcpPort, udpPort, maxPeers int) *Config { +func NewNetConfig(keys testing.NodeKeys, operatorPubKeyHash string, bn *discovery.Bootnode, tcpPort, udpPort uint16, maxPeers int) *Config { bns := "" discT := "discv5" if bn != nil { diff --git a/network/records/entries.go b/network/records/entries.go index cda23dd372..846e7d938d 100644 --- a/network/records/entries.go +++ b/network/records/entries.go @@ -71,7 +71,7 @@ func GetDomainTypeEntry(record *enr.Record, key ENRKey) (spectypes.DomainType, e // SetSubnetsEntry adds subnets entry to our enode.LocalNode func SetSubnetsEntry(node *enode.LocalNode, subnets []byte) error { subnetsVec := bitfield.NewBitvector128() - for i, subnet := range subnets { + for i, subnet := range subnets { // #nosec G115 -- subnets has a constant len of 128 subnetsVec.SetBitAt(uint64(i), subnet > 0) } node.Set(enr.WithEntry("subnets", &subnetsVec)) diff --git a/network/records/subnets.go b/network/records/subnets.go index 58dabb5c7d..de3f2e3faa 100644 --- a/network/records/subnets.go +++ b/network/records/subnets.go @@ -21,7 +21,7 @@ const ( // UpdateSubnets updates subnets entry according to the given changes. // count is the amount of subnets, in case that the entry doesn't exist as we want to initialize it -func UpdateSubnets(node *enode.LocalNode, count int, added []int, removed []int) ([]byte, error) { +func UpdateSubnets(node *enode.LocalNode, count int, added []uint64, removed []uint64) ([]byte, error) { subnets, err := GetSubnetsEntry(node.Node().Record()) if err != nil && !errors.Is(err, ErrEntryNotFound) { return nil, errors.Wrap(err, "could not read subnets entry") @@ -59,8 +59,10 @@ func (s Subnets) Clone() Subnets { func (s Subnets) String() string { subnetsVec := bitfield.NewBitvector128() - for subnet, val := range s { - subnetsVec.SetBitAt(uint64(subnet), val > uint8(0)) + subnet := uint64(0) + for _, val := range s { + subnetsVec.SetBitAt(subnet, val > uint8(0)) + subnet++ } return hex.EncodeToString(subnetsVec.Bytes()) } @@ -144,7 +146,7 @@ func getCharMask(str string) ([]byte, error) { if err != nil { return nil, err } - maskData = append(maskData, uint8(val)) + maskData = append(maskData, uint8(val)) // nolint:gosec } return maskData, nil } diff --git a/network/records/test_utils.go b/network/records/test_utils.go index 83370744ac..d795b42d72 100644 --- a/network/records/test_utils.go +++ b/network/records/test_utils.go @@ -10,7 +10,7 @@ import ( ) // CreateLocalNode create a new enode.LocalNode instance -func CreateLocalNode(privKey *ecdsa.PrivateKey, storagePath string, ipAddr net.IP, udpPort, tcpPort int) (*enode.LocalNode, error) { +func CreateLocalNode(privKey *ecdsa.PrivateKey, storagePath string, ipAddr net.IP, udpPort, tcpPort uint16) (*enode.LocalNode, error) { db, err := enode.OpenDB(storagePath) if err != nil { return nil, errors.Wrap(err, "could not open node's peer database") @@ -21,7 +21,7 @@ func CreateLocalNode(privKey *ecdsa.PrivateKey, storagePath string, ipAddr net.I localNode.Set(enr.UDP(udpPort)) localNode.Set(enr.TCP(tcpPort)) localNode.SetFallbackIP(ipAddr) - localNode.SetFallbackUDP(udpPort) + localNode.SetFallbackUDP(int(udpPort)) return localNode, nil } diff --git a/network/testing/keys.go b/network/testing/keys.go index bed84ae678..49dee5fe6a 100644 --- a/network/testing/keys.go +++ b/network/testing/keys.go @@ -7,6 +7,7 @@ import ( "github.com/herumi/bls-eth-go-binary/bls" spectestingutils "github.com/ssvlabs/ssv-spec/types/testingutils" + "github.com/ssvlabs/ssv/network" "github.com/ssvlabs/ssv/network/commons" "github.com/ssvlabs/ssv/operator/keys" @@ -83,7 +84,8 @@ func NewLocalTestnetFromKeySet(ctx context.Context, factory NetworkFactory, ks * return nil, nil, err } - for i, k := range keys { + i := uint64(0) + for _, k := range keys { nodes[i] = factory(ctx, i, k) } diff --git a/network/testing/local.go b/network/testing/local.go index 97c8ee7d46..ae1ed9acf9 100644 --- a/network/testing/local.go +++ b/network/testing/local.go @@ -2,11 +2,12 @@ package testing import ( "context" + "github.com/ssvlabs/ssv/network" ) // NetworkFactory is a generic factory for network instances -type NetworkFactory func(pctx context.Context, nodeIndex int, keys NodeKeys) network.P2PNetwork +type NetworkFactory func(pctx context.Context, nodeIndex uint64, keys NodeKeys) network.P2PNetwork // NewLocalTestnet creates a new local network func NewLocalTestnet(ctx context.Context, n int, factory NetworkFactory) ([]network.P2PNetwork, []NodeKeys, error) { @@ -16,8 +17,10 @@ func NewLocalTestnet(ctx context.Context, n int, factory NetworkFactory) ([]netw return nil, nil, err } - for i, k := range keys { + i := uint64(0) + for _, k := range keys { nodes[i] = factory(ctx, i, k) + i++ } return nodes, keys, nil diff --git a/network/testing/net.go b/network/testing/net.go index e5205efdc9..048332ed3e 100644 --- a/network/testing/net.go +++ b/network/testing/net.go @@ -8,7 +8,7 @@ import ( ) // RandomTCPPort returns a new random tcp port -func RandomTCPPort(from, to int) int { +func RandomTCPPort(from, to uint16) uint16 { for { port := random(from, to) if checkTCPPort(port) == nil { @@ -20,7 +20,7 @@ func RandomTCPPort(from, to int) int { } // checkTCPPort checks that the given port is not taken -func checkTCPPort(port int) error { +func checkTCPPort(port uint16) error { conn, err := net.DialTimeout("tcp", fmt.Sprintf(":%d", port), 3*time.Second) if err != nil { return err @@ -33,12 +33,12 @@ func checkTCPPort(port int) error { type UDPPortsRandomizer map[int]bool // Next generates a new random port that is available -func (up UDPPortsRandomizer) Next(from, to int) int { +func (up UDPPortsRandomizer) Next(from, to uint16) uint16 { udpPort := random(from, to) udpPortLoop: for { - if !up[udpPort] { - up[udpPort] = true + if !up[int(udpPort)] { + up[int(udpPort)] = true break udpPortLoop } udpPort = random(from, to) @@ -46,7 +46,8 @@ udpPortLoop: return udpPort } -func random(from, to int) int { +func random(from, to uint16) uint16 { // #nosec G404 - return rand.Intn(to-from) + from + // #nosec G115 + return uint16(rand.Intn(int(to-from)) + int(from)) } diff --git a/network/topics/params/message_rate_test.go b/network/topics/params/message_rate_test.go index eef3a0b0e8..75db598f7a 100644 --- a/network/topics/params/message_rate_test.go +++ b/network/topics/params/message_rate_test.go @@ -5,9 +5,10 @@ import ( "github.com/attestantio/go-eth2-client/spec/phase0" spectypes "github.com/ssvlabs/ssv-spec/types" + "github.com/stretchr/testify/require" + "github.com/ssvlabs/ssv/protocol/v2/types" "github.com/ssvlabs/ssv/registry/storage" - "github.com/stretchr/testify/require" ) func createTestingValidators(n int) []*types.SSVShare { @@ -22,10 +23,10 @@ func createTestingValidators(n int) []*types.SSVShare { return ret } -func createTestingSingleCommittees(n int) []*storage.Committee { +func createTestingSingleCommittees(n uint64) []*storage.Committee { ret := make([]*storage.Committee, 0) - for i := 0; i <= n; i++ { - opRef := uint64(i*4 + 1) + for i := uint64(0); i <= n; i++ { + opRef := i*4 + 1 ret = append(ret, &storage.Committee{ Operators: []uint64{opRef, opRef + 1, opRef + 2, opRef + 3}, Validators: createTestingValidators(1), diff --git a/network/topics/params/scores_test.go b/network/topics/params/scores_test.go index ccb172bf59..acf9dc8f12 100644 --- a/network/topics/params/scores_test.go +++ b/network/topics/params/scores_test.go @@ -7,8 +7,9 @@ import ( "time" pubsub "github.com/libp2p/go-libp2p-pubsub" - "github.com/ssvlabs/ssv/registry/storage" "github.com/stretchr/testify/require" + + "github.com/ssvlabs/ssv/registry/storage" ) func TestTopicScoreParams(t *testing.T) { @@ -20,7 +21,7 @@ func TestTopicScoreParams(t *testing.T) { { "subnet topic 0 validators", func() *Options { - validators := 0 + validators := uint64(0) opts := NewSubnetTopicOpts(validators, 128, []*storage.Committee{}) return opts }, @@ -29,7 +30,7 @@ func TestTopicScoreParams(t *testing.T) { { "subnet topic 1k validators", func() *Options { - validators := 1000 + validators := uint64(1000) opts := NewSubnetTopicOpts(validators, 128, createTestingSingleCommittees(validators)) return opts }, @@ -38,7 +39,7 @@ func TestTopicScoreParams(t *testing.T) { { "subnet topic 10k validators", func() *Options { - validators := 10_000 + validators := uint64(10_000) opts := NewSubnetTopicOpts(validators, 128, createTestingSingleCommittees(validators)) return opts }, @@ -47,7 +48,7 @@ func TestTopicScoreParams(t *testing.T) { { "subnet topic 51k validators", func() *Options { - validators := 51_000 + validators := uint64(51_000) opts := NewSubnetTopicOpts(validators, 128, createTestingSingleCommittees(validators)) return opts }, diff --git a/network/topics/params/topic_score.go b/network/topics/params/topic_score.go index ddbee3967a..54613631f6 100644 --- a/network/topics/params/topic_score.go +++ b/network/topics/params/topic_score.go @@ -6,6 +6,7 @@ import ( pubsub "github.com/libp2p/go-libp2p-pubsub" "github.com/pkg/errors" + "github.com/ssvlabs/ssv/registry/storage" ) @@ -46,7 +47,7 @@ var ( // NetworkOpts is the config struct for network configurations type NetworkOpts struct { // ActiveValidators is the amount of validators in the network - ActiveValidators int + ActiveValidators uint64 // Subnets is the number of subnets in the network Subnets int // OneEpochDuration is used as a time-frame length to control scoring in a dynamic way @@ -149,7 +150,7 @@ func (o *Options) maxScore() float64 { } // NewOpts creates new TopicOpts instance -func NewOpts(activeValidators, subnets int) *Options { +func NewOpts(activeValidators uint64, subnets int) *Options { return &Options{ Network: NetworkOpts{ ActiveValidators: activeValidators, @@ -160,7 +161,7 @@ func NewOpts(activeValidators, subnets int) *Options { } // NewSubnetTopicOpts creates new TopicOpts for a subnet topic -func NewSubnetTopicOpts(activeValidators, subnets int, committees []*storage.Committee) *Options { +func NewSubnetTopicOpts(activeValidators uint64, subnets int, committees []*storage.Committee) *Options { // Create options with default values opts := NewOpts(activeValidators, subnets) opts.defaults() @@ -175,7 +176,7 @@ func NewSubnetTopicOpts(activeValidators, subnets int, committees []*storage.Com } // NewSubnetTopicOpts creates new TopicOpts for a subnet topic -func NewSubnetTopicOptsValidators(activeValidators, subnets int) *Options { +func NewSubnetTopicOptsValidators(activeValidators uint64, subnets int) *Options { // Create options with default values opts := NewOpts(activeValidators, subnets) opts.defaults() diff --git a/network/topics/scoring.go b/network/topics/scoring.go index 68036b1fa2..5bda80e447 100644 --- a/network/topics/scoring.go +++ b/network/topics/scoring.go @@ -216,7 +216,7 @@ func topicScoreParams(logger *zap.Logger, cfg *PubSubConfig, committeesProvider logger.Debug("got filtered committees for score params") // Create topic options - opts := params.NewSubnetTopicOpts(int(totalValidators), commons.Subnets(), topicCommittees) + opts := params.NewSubnetTopicOpts(totalValidators, commons.Subnets(), topicCommittees) // Generate topic parameters tp, err := params.TopicParams(opts) @@ -239,7 +239,7 @@ func validatorTopicScoreParams(logger *zap.Logger, cfg *PubSubConfig) func(strin logger := logger.With(zap.String("topic", t), zap.Uint64("totalValidators", totalValidators), zap.Uint64("activeValidators", activeValidators), zap.Uint64("myValidators", myValidators)) logger.Debug("got validator stats for score params") - opts := params.NewSubnetTopicOptsValidators(int(totalValidators), commons.Subnets()) + opts := params.NewSubnetTopicOptsValidators(totalValidators, commons.Subnets()) tp, err := params.TopicParams(opts) if err != nil { logger.Debug("ignoring topic score params", zap.Error(err)) diff --git a/networkconfig/config.go b/networkconfig/config.go index 15f9d5adad..fcfb001996 100644 --- a/networkconfig/config.go +++ b/networkconfig/config.go @@ -89,7 +89,7 @@ func (n NetworkConfig) SlotsPerEpoch() uint64 { // GetGenesisTime returns the genesis time in unix time. func (n NetworkConfig) GetGenesisTime() time.Time { - return time.Unix(int64(n.Beacon.MinGenesisTime()), 0) + return time.Unix(n.Beacon.MinGenesisTime(), 0) } // DomainType returns current domain type based on the current fork. diff --git a/operator/duties/dutystore/voluntary_exit.go b/operator/duties/dutystore/voluntary_exit.go index d742753645..b664523c2e 100644 --- a/operator/duties/dutystore/voluntary_exit.go +++ b/operator/duties/dutystore/voluntary_exit.go @@ -8,16 +8,16 @@ import ( type VoluntaryExitDuties struct { mu sync.RWMutex - m map[phase0.Slot]map[phase0.BLSPubKey]int + m map[phase0.Slot]map[phase0.BLSPubKey]uint64 } func NewVoluntaryExit() *VoluntaryExitDuties { return &VoluntaryExitDuties{ - m: make(map[phase0.Slot]map[phase0.BLSPubKey]int), + m: make(map[phase0.Slot]map[phase0.BLSPubKey]uint64), } } -func (d *VoluntaryExitDuties) GetDutyCount(slot phase0.Slot, pk phase0.BLSPubKey) int { +func (d *VoluntaryExitDuties) GetDutyCount(slot phase0.Slot, pk phase0.BLSPubKey) uint64 { d.mu.RLock() defer d.mu.RUnlock() @@ -35,7 +35,7 @@ func (d *VoluntaryExitDuties) AddDuty(slot phase0.Slot, pk phase0.BLSPubKey) { v, ok := d.m[slot] if !ok { - d.m[slot] = map[phase0.BLSPubKey]int{ + d.m[slot] = map[phase0.BLSPubKey]uint64{ pk: 1, } } else { diff --git a/operator/duties/scheduler.go b/operator/duties/scheduler.go index 0cdc2db1ae..2c42b4c268 100644 --- a/operator/duties/scheduler.go +++ b/operator/duties/scheduler.go @@ -29,6 +29,7 @@ import ( "github.com/ssvlabs/ssv/operator/duties/dutystore" "github.com/ssvlabs/ssv/operator/slotticker" "github.com/ssvlabs/ssv/protocol/v2/types" + "github.com/ssvlabs/ssv/utils/casts" ) //go:generate mockgen -package=duties -destination=./scheduler_mock.go -source=./scheduler.go @@ -272,7 +273,7 @@ func (s *Scheduler) SlotTicker(ctx context.Context) { case <-s.ticker.Next(): slot := s.ticker.Slot() - delay := s.network.SlotDurationSec() / time.Duration(goclient.IntervalsPerSlot) /* a third of the slot duration */ + delay := s.network.SlotDurationSec() / casts.DurationFromUint64(goclient.IntervalsPerSlot) /* a third of the slot duration */ finalTime := s.network.Beacon.GetSlotStartTime(slot).Add(delay) waitDuration := time.Until(finalTime) @@ -357,7 +358,7 @@ func (s *Scheduler) HandleHeadEvent(logger *zap.Logger) func(event *eth2apiv1.Ev s.currentDutyDependentRoot = data.CurrentDutyDependentRoot currentTime := time.Now() - delay := s.network.SlotDurationSec() / time.Duration(goclient.IntervalsPerSlot) /* a third of the slot duration */ + delay := s.network.SlotDurationSec() / casts.DurationFromUint64(goclient.IntervalsPerSlot) /* a third of the slot duration */ slotStartTimeWithDelay := s.network.Beacon.GetSlotStartTime(data.Slot).Add(delay) if currentTime.Before(slotStartTimeWithDelay) { logger.Debug("🏁 Head event: Block arrived before 1/3 slot", zap.Duration("time_saved", slotStartTimeWithDelay.Sub(currentTime))) diff --git a/operator/duties/scheduler_test.go b/operator/duties/scheduler_test.go index 29034820d9..e963e782ed 100644 --- a/operator/duties/scheduler_test.go +++ b/operator/duties/scheduler_test.go @@ -122,7 +122,7 @@ func setupSchedulerAndMocks(t *testing.T, handlers []dutyHandler, currentSlot *S mockBeaconNode.EXPECT().Events(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) - mockNetworkConfig.Beacon.(*mocknetwork.MockBeaconNetwork).EXPECT().MinGenesisTime().Return(uint64(0)).AnyTimes() + mockNetworkConfig.Beacon.(*mocknetwork.MockBeaconNetwork).EXPECT().MinGenesisTime().Return(int64(0)).AnyTimes() mockNetworkConfig.Beacon.(*mocknetwork.MockBeaconNetwork).EXPECT().SlotDurationSec().Return(150 * time.Millisecond).AnyTimes() mockNetworkConfig.Beacon.(*mocknetwork.MockBeaconNetwork).EXPECT().SlotsPerEpoch().Return(uint64(32)).AnyTimes() mockNetworkConfig.Beacon.(*mocknetwork.MockBeaconNetwork).EXPECT().GetSlotStartTime(gomock.Any()).DoAndReturn( diff --git a/operator/duties/voluntary_exit.go b/operator/duties/voluntary_exit.go index f4a03e8fb5..b89c2d7fc1 100644 --- a/operator/duties/voluntary_exit.go +++ b/operator/duties/voluntary_exit.go @@ -2,9 +2,10 @@ package duties import ( "context" - genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" "math/big" + genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" + "github.com/attestantio/go-eth2-client/spec/phase0" spectypes "github.com/ssvlabs/ssv-spec/types" "go.uber.org/zap" @@ -162,7 +163,7 @@ func (h *VoluntaryExitHandler) blockSlot(ctx context.Context, blockNumber uint64 return 0, err } - blockSlot = h.network.Beacon.EstimatedSlotAtTime(int64(block.Time())) + blockSlot = h.network.Beacon.EstimatedSlotAtTime(int64(block.Time())) // #nosec G115 h.blockSlots[blockNumber] = blockSlot for k, v := range h.blockSlots { diff --git a/operator/slotticker/slotticker.go b/operator/slotticker/slotticker.go index 17a2da8458..098a75b2bf 100644 --- a/operator/slotticker/slotticker.go +++ b/operator/slotticker/slotticker.go @@ -4,6 +4,7 @@ import ( "time" "github.com/attestantio/go-eth2-client/spec/phase0" + "github.com/ssvlabs/ssv/utils/casts" "go.uber.org/zap" ) @@ -72,13 +73,13 @@ func (s *slotTicker) Next() <-chan time.Time { default: } } - nextSlot := phase0.Slot(timeSinceGenesis/s.slotDuration) + 1 + nextSlot := phase0.Slot(timeSinceGenesis/s.slotDuration) + 1 // #nosec G115 if nextSlot <= s.slot { // We've already ticked for this slot, so we need to wait for the next one. nextSlot = s.slot + 1 s.logger.Debug("double tick", zap.Uint64("slot", uint64(s.slot))) } - nextSlotStartTime := s.genesisTime.Add(time.Duration(nextSlot) * s.slotDuration) + nextSlotStartTime := s.genesisTime.Add(casts.DurationFromUint64(uint64(nextSlot)) * s.slotDuration) s.timer.Reset(time.Until(nextSlotStartTime)) s.slot = nextSlot return s.timer.C() diff --git a/operator/validator/controller.go b/operator/validator/controller.go index 6069235912..de3e9dbd23 100644 --- a/operator/validator/controller.go +++ b/operator/validator/controller.go @@ -22,7 +22,6 @@ import ( "go.uber.org/zap" "github.com/ssvlabs/ssv/exporter/convert" - "github.com/ssvlabs/ssv/ibft/genesisstorage" "github.com/ssvlabs/ssv/ibft/storage" "github.com/ssvlabs/ssv/logging" @@ -429,7 +428,7 @@ func (c *controller) handleRouterMessages() { } } -var nonCommitteeValidatorTTLs = map[spectypes.RunnerRole]phase0.Slot{ +var nonCommitteeValidatorTTLs = map[spectypes.RunnerRole]int{ spectypes.RoleCommittee: 64, spectypes.RoleProposer: 4, spectypes.RoleAggregator: 4, @@ -1002,7 +1001,7 @@ func (c *controller) committeeMemberFromShare(share *ssvtypes.SSVShare) (*specty } } - f := ssvtypes.ComputeF(len(share.Committee)) + f := ssvtypes.ComputeF(uint64(len(share.Committee))) operatorPEM, err := base64.StdEncoding.DecodeString(string(c.operatorDataStore.GetOperatorData().PublicKey)) if err != nil { @@ -1243,7 +1242,7 @@ func SetupCommitteeRunners( Storage: options.Storage.Get(convert.RunnerRole(role)), Network: options.Network, Timer: roundtimer.New(ctx, options.NetworkConfig.Beacon, role, nil), - CutOffRound: specqbft.Round(specqbft.CutoffRound), + CutOffRound: roundtimer.CutOffRound, } identifier := spectypes.NewMsgID(options.NetworkConfig.AlanDomainType, options.Operator.CommitteeID[:], role) @@ -1307,7 +1306,7 @@ func SetupRunners( Storage: options.Storage.Get(convert.RunnerRole(role)), Network: options.Network, Timer: roundtimer.New(ctx, options.NetworkConfig.Beacon, role, nil), - CutOffRound: specqbft.Round(specqbft.CutoffRound), + CutOffRound: roundtimer.CutOffRound, } config.ValueCheckF = valueCheckF diff --git a/protocol/genesis/qbft/instance/instance.go b/protocol/genesis/qbft/instance/instance.go index c61f1007a4..18c0f5917f 100644 --- a/protocol/genesis/qbft/instance/instance.go +++ b/protocol/genesis/qbft/instance/instance.go @@ -255,5 +255,5 @@ func (i *Instance) bumpToRound(round genesisspecqbft.Round) { // CanProcessMessages will return true if instance can process messages func (i *Instance) CanProcessMessages() bool { - return !i.forceStop && int(i.State.Round) < CutoffRound + return !i.forceStop && uint64(i.State.Round) < CutoffRound } diff --git a/protocol/genesis/qbft/instance/timeout.go b/protocol/genesis/qbft/instance/timeout.go index f424bead0c..7232c627b4 100644 --- a/protocol/genesis/qbft/instance/timeout.go +++ b/protocol/genesis/qbft/instance/timeout.go @@ -5,10 +5,11 @@ import ( "go.uber.org/zap" specqbft "github.com/ssvlabs/ssv-spec/qbft" + "github.com/ssvlabs/ssv/logging/fields" ) -var CutoffRound = 15 // stop processing instances after 8*2+120*6 = 14.2 min (~ 2 epochs) +var CutoffRound = uint64(15) // stop processing instances after 8*2+120*6 = 14.2 min (~ 2 epochs) func (i *Instance) UponRoundTimeout(logger *zap.Logger) error { if !i.CanProcessMessages() { diff --git a/protocol/genesis/qbft/roundtimer/timer.go b/protocol/genesis/qbft/roundtimer/timer.go index 35a4709fa8..43854dd3ae 100644 --- a/protocol/genesis/qbft/roundtimer/timer.go +++ b/protocol/genesis/qbft/roundtimer/timer.go @@ -9,6 +9,7 @@ import ( "github.com/attestantio/go-eth2-client/spec/phase0" genesisspecqbft "github.com/ssvlabs/ssv-spec-pre-cc/qbft" genesisspectypes "github.com/ssvlabs/ssv-spec-pre-cc/types" + "github.com/ssvlabs/ssv/utils/casts" ) //go:generate mockgen -package=mocks -destination=./mocks/timer.go -source=./timer.go @@ -120,10 +121,10 @@ func (t *RoundTimer) RoundTimeout(height genesisspecqbft.Height, round genesissp // Calculate additional timeout based on round var additionalTimeout time.Duration if round <= t.timeoutOptions.quickThreshold { - additionalTimeout = time.Duration(int(round)) * t.timeoutOptions.quick + additionalTimeout = casts.DurationFromUint64(uint64(round)) * t.timeoutOptions.quick } else { - quickPortion := time.Duration(t.timeoutOptions.quickThreshold) * t.timeoutOptions.quick - slowPortion := time.Duration(int(round-t.timeoutOptions.quickThreshold)) * t.timeoutOptions.slow + quickPortion := casts.DurationFromUint64(uint64(t.timeoutOptions.quickThreshold)) * t.timeoutOptions.quick + slowPortion := casts.DurationFromUint64(uint64(round-t.timeoutOptions.quickThreshold)) * t.timeoutOptions.slow additionalTimeout = quickPortion + slowPortion } @@ -147,12 +148,12 @@ func (t *RoundTimer) OnTimeout(done OnRoundTimeoutF) { // Round returns a round. func (t *RoundTimer) Round() genesisspecqbft.Round { - return genesisspecqbft.Round(atomic.LoadInt64(&t.round)) + return genesisspecqbft.Round(atomic.LoadInt64(&t.round)) // #nosec G115 } // TimeoutForRound times out for a given round. func (t *RoundTimer) TimeoutForRound(height genesisspecqbft.Height, round genesisspecqbft.Round) { - atomic.StoreInt64(&t.round, int64(round)) + atomic.StoreInt64(&t.round, int64(round)) // #nosec G115 timeout := t.RoundTimeout(height, round) // preparing the underlying timer diff --git a/protocol/genesis/qbft/spectest/controller_type.go b/protocol/genesis/qbft/spectest/controller_type.go index cbb51cdb83..1b4c84f0cf 100644 --- a/protocol/genesis/qbft/spectest/controller_type.go +++ b/protocol/genesis/qbft/spectest/controller_type.go @@ -38,14 +38,15 @@ func RunControllerSpecTest(t *testing.T, test *spectests.ControllerSpecTest) { } var lastErr error - for i, runData := range test.RunInstanceData { - height := genesisspecqbft.Height(i) + height := genesisspecqbft.Height(0) + for _, runData := range test.RunInstanceData { if runData.Height != nil { height = *runData.Height } if err := runInstanceWithData(t, logger, height, contr, runData); err != nil { lastErr = err } + height++ } if len(test.ExpectedError) != 0 { diff --git a/protocol/genesis/ssv/genesisqueue/messages.go b/protocol/genesis/ssv/genesisqueue/messages.go index d2cc3f9824..fededfafc0 100644 --- a/protocol/genesis/ssv/genesisqueue/messages.go +++ b/protocol/genesis/ssv/genesisqueue/messages.go @@ -247,5 +247,5 @@ func isDecidedMesssage(s *State, sm *genesisspecqbft.SignedMessage) bool { return false } return sm.Message.MsgType == genesisspecqbft.CommitMsgType && - len(sm.Signers) > int(s.Quorum) + uint64(len(sm.Signers)) > s.Quorum } diff --git a/protocol/genesis/ssv/spectest/msg_processing_type.go b/protocol/genesis/ssv/spectest/msg_processing_type.go index b865e12a8e..ae8132faf4 100644 --- a/protocol/genesis/ssv/spectest/msg_processing_type.go +++ b/protocol/genesis/ssv/spectest/msg_processing_type.go @@ -15,6 +15,7 @@ import ( "go.uber.org/zap" typescomparable "github.com/ssvlabs/ssv-spec-pre-cc/types/testingutils/comparable" + "github.com/ssvlabs/ssv/logging" "github.com/ssvlabs/ssv/protocol/genesis/ssv/genesisqueue" "github.com/ssvlabs/ssv/protocol/genesis/ssv/runner" diff --git a/protocol/genesis/ssv/validator/msgqueue_consumer.go b/protocol/genesis/ssv/validator/msgqueue_consumer.go index e5bf69286f..269003de99 100644 --- a/protocol/genesis/ssv/validator/msgqueue_consumer.go +++ b/protocol/genesis/ssv/validator/msgqueue_consumer.go @@ -14,7 +14,7 @@ import ( "github.com/ssvlabs/ssv/logging/fields" "github.com/ssvlabs/ssv/protocol/genesis/message" "github.com/ssvlabs/ssv/protocol/genesis/qbft/instance" - genesisqueue "github.com/ssvlabs/ssv/protocol/genesis/ssv/genesisqueue" + "github.com/ssvlabs/ssv/protocol/genesis/ssv/genesisqueue" "github.com/ssvlabs/ssv/protocol/genesis/types" ) @@ -45,7 +45,7 @@ func (v *Validator) HandleMessage(logger *zap.Logger, msg *genesisqueue.GenesisS zap.String("msg_type", message.MsgTypeToString(msg.MsgType)), zap.String("msg_id", msgID)) } - logger.Debug("📬 queue: pushed message", fields.MessageID(spectypes.MessageID(msg.MsgID)), fields.MessageType(spectypes.MsgType(msg.MsgType))) + //logger.Debug("📬 queue: pushed message", fields.MessageID(spectypes.MessageID(msg.MsgID)), fields.MessageType(spectypes.MsgType(msg.MsgType))) } else { logger.Error("❌ missing queue for role type", fields.BeaconRole(spectypes.BeaconRole(msg.MsgID.GetRoleType()))) } @@ -168,15 +168,15 @@ func (v *Validator) logMsg(logger *zap.Logger, msg *genesisqueue.GenesisSSVMessa case genesisspectypes.SSVConsensusMsgType: sm := msg.Body.(*genesisspecqbft.SignedMessage) baseFields = []zap.Field{ - zap.Int64("msg_height", int64(sm.Message.Height)), - zap.Int64("msg_round", int64(sm.Message.Round)), - zap.Int64("consensus_msg_type", int64(sm.Message.MsgType)), + zap.Uint64("msg_height", uint64(sm.Message.Height)), + zap.Uint64("msg_round", uint64(sm.Message.Round)), + zap.Uint64("consensus_msg_type", uint64(sm.Message.MsgType)), zap.Any("signers", sm.Signers), } case genesisspectypes.SSVPartialSignatureMsgType: psm := msg.Body.(*genesisspectypes.SignedPartialSignatureMessage) baseFields = []zap.Field{ - zap.Int64("signer", int64(psm.Signer)), + zap.Uint64("signer", psm.Signer), fields.Slot(psm.Message.Slot), } } diff --git a/protocol/genesis/testing/test_utils.go b/protocol/genesis/testing/test_utils.go index f9e1ed5b4a..764feb7fbf 100644 --- a/protocol/genesis/testing/test_utils.go +++ b/protocol/genesis/testing/test_utils.go @@ -34,12 +34,12 @@ func GenerateBLSKeys(oids ...genesisspectypes.OperatorID) (map[genesisspectypes. nodes := make([]*genesisspectypes.Operator, 0) sks := make(map[genesisspectypes.OperatorID]*bls.SecretKey) - for i, oid := range oids { + for _, oid := range oids { sk := &bls.SecretKey{} sk.SetByCSPRNG() nodes = append(nodes, &genesisspectypes.Operator{ - OperatorID: genesisspectypes.OperatorID(i), + OperatorID: oid, PubKey: sk.GetPublicKey().Serialize(), }) sks[oid] = sk diff --git a/protocol/genesis/types/share.go b/protocol/genesis/types/share.go index ba208bd077..9766490159 100644 --- a/protocol/genesis/types/share.go +++ b/protocol/genesis/types/share.go @@ -8,7 +8,7 @@ import ( ) func ConvertToGenesisShare(share *spectypes.Share, operator *spectypes.CommitteeMember) *genesisspectypes.Share { - q, pc := ComputeQuorumAndPartialQuorum(len(share.Committee)) + q, pc := ComputeQuorumAndPartialQuorum(uint64(len((share.Committee)))) key := make([]byte, len(share.ValidatorPubKey)) copy(key, share.ValidatorPubKey[:]) diff --git a/protocol/genesis/types/ssvshare.go b/protocol/genesis/types/ssvshare.go index 5beaba666b..d2659ee60d 100644 --- a/protocol/genesis/types/ssvshare.go +++ b/protocol/genesis/types/ssvshare.go @@ -50,7 +50,7 @@ func (s *SSVShare) Decode(data []byte) error { if err := d.Decode(s); err != nil { return fmt.Errorf("decode SSVShare: %w", err) } - s.Quorum, s.PartialQuorum = ComputeQuorumAndPartialQuorum(len(s.Committee)) + s.Quorum, s.PartialQuorum = ComputeQuorumAndPartialQuorum(uint64(len(s.Committee))) return nil } @@ -93,9 +93,9 @@ func ComputeClusterIDHash(address common.Address, operatorIds []uint64) []byte { return hash } -func ComputeQuorumAndPartialQuorum(committeeSize int) (quorum uint64, partialQuorum uint64) { +func ComputeQuorumAndPartialQuorum(committeeSize uint64) (quorum uint64, partialQuorum uint64) { f := (committeeSize - 1) / 3 - return uint64(f*2 + 1), uint64(f + 1) + return f*2 + 1, f + 1 } func ValidCommitteeSize(committeeSize int) bool { diff --git a/protocol/v2/blockchain/beacon/mocks/network.go b/protocol/v2/blockchain/beacon/mocks/network.go index a8bf74f046..5e1b378809 100644 --- a/protocol/v2/blockchain/beacon/mocks/network.go +++ b/protocol/v2/blockchain/beacon/mocks/network.go @@ -1,9 +1,9 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: ./network.go +// Source: ./protocol/v2/blockchain/beacon/network.go // // Generated by this command: // -// mockgen -package=mocks -destination=./mocks/network.go -source=./network.go +// mockgen -package=mocks -destination=./protocol/v2/blockchain/beacon/mocks/network.go -source=./protocol/v2/blockchain/beacon/network.go // // Package mocks is a generated GoMock package. @@ -295,10 +295,10 @@ func (mr *MockBeaconNetworkMockRecorder) LastSlotOfSyncPeriod(period any) *gomoc } // MinGenesisTime mocks base method. -func (m *MockBeaconNetwork) MinGenesisTime() uint64 { +func (m *MockBeaconNetwork) MinGenesisTime() int64 { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MinGenesisTime") - ret0, _ := ret[0].(uint64) + ret0, _ := ret[0].(int64) return ret0 } diff --git a/protocol/v2/blockchain/beacon/network.go b/protocol/v2/blockchain/beacon/network.go index e4876b009b..c47fa700ed 100644 --- a/protocol/v2/blockchain/beacon/network.go +++ b/protocol/v2/blockchain/beacon/network.go @@ -17,7 +17,7 @@ type Network struct { type BeaconNetwork interface { ForkVersion() [4]byte - MinGenesisTime() uint64 + MinGenesisTime() int64 SlotDurationSec() time.Duration SlotsPerEpoch() uint64 EstimatedCurrentSlot() phase0.Slot @@ -59,11 +59,11 @@ func NewLocalTestNetwork(network spectypes.BeaconNetwork) Network { } // MinGenesisTime returns min genesis time value -func (n Network) MinGenesisTime() uint64 { +func (n Network) MinGenesisTime() int64 { if n.LocalTestNet { return 1689072978 } - return n.BeaconNetwork.MinGenesisTime() + return int64(n.BeaconNetwork.MinGenesisTime()) // #nosec G115 } // GetNetwork returns the network @@ -78,8 +78,8 @@ func (n Network) GetBeaconNetwork() spectypes.BeaconNetwork { // GetSlotStartTime returns the start time for the given slot func (n Network) GetSlotStartTime(slot phase0.Slot) time.Time { - timeSinceGenesisStart := uint64(slot) * uint64(n.SlotDurationSec().Seconds()) - start := time.Unix(int64(n.MinGenesisTime()+timeSinceGenesisStart), 0) + timeSinceGenesisStart := int64(uint64(slot) * uint64(n.SlotDurationSec().Seconds())) // #nosec G115 + start := time.Unix(n.MinGenesisTime()+timeSinceGenesisStart, 0) return start } @@ -95,11 +95,11 @@ func (n Network) EstimatedCurrentSlot() phase0.Slot { // EstimatedSlotAtTime estimates slot at the given time func (n Network) EstimatedSlotAtTime(time int64) phase0.Slot { - genesis := int64(n.MinGenesisTime()) + genesis := n.MinGenesisTime() if time < genesis { return 0 } - return phase0.Slot(uint64(time-genesis) / uint64(n.SlotDurationSec().Seconds())) + return phase0.Slot(uint64(time-genesis) / uint64(n.SlotDurationSec().Seconds())) //#nosec G115 } // EstimatedCurrentEpoch estimates the current epoch diff --git a/protocol/v2/qbft/config.go b/protocol/v2/qbft/config.go index 4042d9a4f0..1d356fd582 100644 --- a/protocol/v2/qbft/config.go +++ b/protocol/v2/qbft/config.go @@ -8,6 +8,8 @@ import ( qbftstorage "github.com/ssvlabs/ssv/protocol/v2/qbft/storage" ) +var CutOffRound specqbft.Round = specqbft.Round(specqbft.CutoffRound) + type signing interface { // GetShareSigner returns a BeaconSigner instance GetShareSigner() spectypes.BeaconSigner diff --git a/protocol/v2/qbft/round_robin_proposer.go b/protocol/v2/qbft/round_robin_proposer.go index cf02051705..c4117770ca 100644 --- a/protocol/v2/qbft/round_robin_proposer.go +++ b/protocol/v2/qbft/round_robin_proposer.go @@ -10,11 +10,11 @@ import ( // Each new height has a different first round proposer which is +1 from the previous height. // First height starts with index 0 func RoundRobinProposer(state *qbft.State, round qbft.Round) types.OperatorID { - firstRoundIndex := 0 + firstRoundIndex := uint64(0) if state.Height != qbft.FirstHeight { - firstRoundIndex += int(state.Height) % len(state.CommitteeMember.Committee) + firstRoundIndex += uint64(state.Height) % uint64(len(state.CommitteeMember.Committee)) } - index := (firstRoundIndex + int(round) - int(qbft.FirstRound)) % len(state.CommitteeMember.Committee) + index := (firstRoundIndex + uint64(round) - uint64(qbft.FirstRound)) % uint64(len(state.CommitteeMember.Committee)) return state.CommitteeMember.Committee[index].OperatorID } diff --git a/protocol/v2/qbft/roundtimer/timer.go b/protocol/v2/qbft/roundtimer/timer.go index 820483e5d7..a8bbec5ee2 100644 --- a/protocol/v2/qbft/roundtimer/timer.go +++ b/protocol/v2/qbft/roundtimer/timer.go @@ -9,6 +9,7 @@ import ( "github.com/attestantio/go-eth2-client/spec/phase0" specqbft "github.com/ssvlabs/ssv-spec/qbft" spectypes "github.com/ssvlabs/ssv-spec/types" + "github.com/ssvlabs/ssv/utils/casts" ) //go:generate mockgen -package=mocks -destination=./mocks/timer.go -source=./timer.go @@ -21,6 +22,8 @@ const ( SlowTimeout = 2 * time.Minute ) +var CutOffRound specqbft.Round = specqbft.Round(specqbft.CutoffRound) + // Timer is an interface for a round timer, calling the UponRoundTimeout when times out type Timer interface { // TimeoutForRound will reset running timer if exists and will start a new timer for a specific round @@ -49,7 +52,7 @@ type RoundTimer struct { // result holds the result of the timer done OnRoundTimeoutF // round is the current round of the timer - round int64 + round uint64 // timeoutOptions holds the timeoutOptions for the timer timeoutOptions TimeoutOptions // role is the role of the instance @@ -120,10 +123,10 @@ func (t *RoundTimer) RoundTimeout(height specqbft.Height, round specqbft.Round) // Calculate additional timeout based on round var additionalTimeout time.Duration if round <= t.timeoutOptions.quickThreshold { - additionalTimeout = time.Duration(int(round)) * t.timeoutOptions.quick + additionalTimeout = casts.DurationFromUint64(uint64(round)) * t.timeoutOptions.quick } else { - quickPortion := time.Duration(t.timeoutOptions.quickThreshold) * t.timeoutOptions.quick - slowPortion := time.Duration(int(round-t.timeoutOptions.quickThreshold)) * t.timeoutOptions.slow + quickPortion := casts.DurationFromUint64(uint64(t.timeoutOptions.quickThreshold)) * t.timeoutOptions.quick + slowPortion := casts.DurationFromUint64(uint64(round-t.timeoutOptions.quickThreshold)) * t.timeoutOptions.slow additionalTimeout = quickPortion + slowPortion } @@ -147,12 +150,12 @@ func (t *RoundTimer) OnTimeout(done OnRoundTimeoutF) { // Round returns a round. func (t *RoundTimer) Round() specqbft.Round { - return specqbft.Round(atomic.LoadInt64(&t.round)) + return specqbft.Round(atomic.LoadUint64(&t.round)) // #nosec G115 } // TimeoutForRound times out for a given round. func (t *RoundTimer) TimeoutForRound(height specqbft.Height, round specqbft.Round) { - atomic.StoreInt64(&t.round, int64(round)) + atomic.StoreUint64(&t.round, uint64(round)) timeout := t.RoundTimeout(height, round) // preparing the underlying timer diff --git a/protocol/v2/qbft/spectest/controller_type.go b/protocol/v2/qbft/spectest/controller_type.go index 37368f96d9..5cf150b850 100644 --- a/protocol/v2/qbft/spectest/controller_type.go +++ b/protocol/v2/qbft/spectest/controller_type.go @@ -5,12 +5,13 @@ import ( "encoding/hex" "encoding/json" "fmt" - "github.com/ssvlabs/ssv/exporter/convert" "os" "path/filepath" "reflect" "testing" + "github.com/ssvlabs/ssv/exporter/convert" + specqbft "github.com/ssvlabs/ssv-spec/qbft" spectests "github.com/ssvlabs/ssv-spec/qbft/spectest/tests" spectypes "github.com/ssvlabs/ssv-spec/types" @@ -39,14 +40,15 @@ func RunControllerSpecTest(t *testing.T, test *spectests.ControllerSpecTest) { } var lastErr error - for i, runData := range test.RunInstanceData { - height := specqbft.Height(i) + height := specqbft.Height(0) + for _, runData := range test.RunInstanceData { if runData.Height != nil { height = *runData.Height } if err := runInstanceWithData(t, logger, height, contr, runData); err != nil { lastErr = err } + height++ } if len(test.ExpectedError) != 0 { diff --git a/protocol/v2/qbft/spectest/msg_processing_type.go b/protocol/v2/qbft/spectest/msg_processing_type.go index 2fb808818b..c11d8ada11 100644 --- a/protocol/v2/qbft/spectest/msg_processing_type.go +++ b/protocol/v2/qbft/spectest/msg_processing_type.go @@ -34,7 +34,7 @@ func RunMsgProcessing(t *testing.T, test *spectests.MsgProcessingSpecTest) { ks := spectestingutils.KeySetForCommitteeMember(test.Pre.State.CommitteeMember) signer := spectestingutils.NewOperatorSigner(ks, 1) pre := instance.NewInstance( - qbfttesting.TestingConfig(logger, ks, convert.RunnerRole(msgId.GetRoleType())), + qbfttesting.TestingConfig(logger, ks, convert.RunnerRole(msgId.GetRoleType())), // #nosec G104 test.Pre.State.CommitteeMember, test.Pre.State.ID, test.Pre.State.Height, diff --git a/protocol/v2/ssv/queue/messages.go b/protocol/v2/ssv/queue/messages.go index e41c8222fe..240046378b 100644 --- a/protocol/v2/ssv/queue/messages.go +++ b/protocol/v2/ssv/queue/messages.go @@ -237,7 +237,7 @@ func isDecidedMessage(s *State, m *SSVMessage) bool { return false } return consensusMessage.MsgType == specqbft.CommitMsgType && - len(m.SignedSSVMessage.OperatorIDs) > int(s.Quorum) + uint64(len(m.SignedSSVMessage.OperatorIDs)) > s.Quorum } // scoreCommitteeMessageSubtype returns an integer score for the message's type. diff --git a/protocol/v2/ssv/runner/committee.go b/protocol/v2/ssv/runner/committee.go index d9b2aa65ef..31fa8095b3 100644 --- a/protocol/v2/ssv/runner/committee.go +++ b/protocol/v2/ssv/runner/committee.go @@ -243,7 +243,7 @@ func (cr *CommitteeRunner) ProcessConsensus(logger *zap.Logger, msg *spectypes.S if err != nil { return errors.Wrap(err, "failed to hash attestation data") } - logger.Debug("signed attestation data", zap.Int("validator_index", int(duty.ValidatorIndex)), + logger.Debug("signed attestation data", zap.Uint64("validator_index", uint64(duty.ValidatorIndex)), zap.String("pub_key", hex.EncodeToString(duty.PubKey[:])), zap.Any("attestation_data", attestationData), zap.String("attestation_data_root", hex.EncodeToString(attDataRoot[:])), @@ -308,20 +308,20 @@ func (cr *CommitteeRunner) ProcessPostConsensus(logger *zap.Logger, signedMsg *s logger = logger.With(fields.Slot(signedMsg.Slot)) // TODO: (Alan) revert? - indices := make([]int, len(signedMsg.Messages)) + indices := make([]uint64, len(signedMsg.Messages)) signers := make([]uint64, len(signedMsg.Messages)) for i, msg := range signedMsg.Messages { signers[i] = msg.Signer - indices[i] = int(msg.ValidatorIndex) + indices[i] = uint64(msg.ValidatorIndex) } logger = logger.With(fields.ConsensusTime(cr.metrics.GetConsensusTime())) logger.Debug("🧩 got partial signatures", zap.Bool("quorum", quorum), fields.Slot(cr.BaseRunner.State.StartingDuty.DutySlot()), - zap.Int("signer", int(signedMsg.Messages[0].Signer)), + zap.Uint64("signer", signedMsg.Messages[0].Signer), zap.Int("sigs", len(roots)), - zap.Ints("validators", indices)) + zap.Uint64s("validators", indices)) if !quorum { return nil @@ -378,7 +378,7 @@ func (cr *CommitteeRunner) ProcessPostConsensus(logger *zap.Logger, signedMsg *s // Reconstruct signature share := cr.BaseRunner.Share[validator] pubKey := share.ValidatorPubKey - vlogger := logger.With(zap.Int("validator_index", int(validator)), zap.String("pubkey", hex.EncodeToString(pubKey[:]))) + vlogger := logger.With(zap.Uint64("validator_index", uint64(validator)), zap.String("pubkey", hex.EncodeToString(pubKey[:]))) sig, err := cr.BaseRunner.State.ReconstructBeaconSig(cr.BaseRunner.State.PostConsensusContainer, root, pubKey[:], validator) diff --git a/protocol/v2/ssv/validator/committee_queue.go b/protocol/v2/ssv/validator/committee_queue.go index b8c2563e7d..bfe8776df7 100644 --- a/protocol/v2/ssv/validator/committee_queue.go +++ b/protocol/v2/ssv/validator/committee_queue.go @@ -161,15 +161,15 @@ func (c *Committee) logMsg(logger *zap.Logger, msg *queue.SSVMessage, logMsg str case spectypes.SSVConsensusMsgType: sm := msg.Body.(*specqbft.Message) baseFields = []zap.Field{ - zap.Int64("msg_height", int64(sm.Height)), - zap.Int64("msg_round", int64(sm.Round)), - zap.Int64("consensus_msg_type", int64(sm.MsgType)), + zap.Uint64("msg_height", uint64(sm.Height)), + zap.Uint64("msg_round", uint64(sm.Round)), + zap.Uint64("consensus_msg_type", uint64(sm.MsgType)), zap.Any("signers", msg.SignedSSVMessage.OperatorIDs), } case spectypes.SSVPartialSignatureMsgType: psm := msg.Body.(*spectypes.PartialSignatureMessages) baseFields = []zap.Field{ - zap.Int64("signer", int64(psm.Messages[0].Signer)), + zap.Uint64("signer", psm.Messages[0].Signer), fields.Slot(psm.Slot), } } diff --git a/protocol/v2/ssv/validator/msgqueue_consumer.go b/protocol/v2/ssv/validator/msgqueue_consumer.go index 9330d51986..502f0ca503 100644 --- a/protocol/v2/ssv/validator/msgqueue_consumer.go +++ b/protocol/v2/ssv/validator/msgqueue_consumer.go @@ -168,15 +168,15 @@ func (v *Validator) logMsg(logger *zap.Logger, msg *queue.SSVMessage, logMsg str qbftMsg := msg.Body.(*specqbft.Message) baseFields = []zap.Field{ - zap.Int64("msg_height", int64(qbftMsg.Height)), - zap.Int64("msg_round", int64(qbftMsg.Round)), - zap.Int64("consensus_msg_type", int64(qbftMsg.MsgType)), + zap.Uint64("msg_height", uint64(qbftMsg.Height)), + zap.Uint64("msg_round", uint64(qbftMsg.Round)), + zap.Uint64("consensus_msg_type", uint64(qbftMsg.MsgType)), zap.Any("signers", msg.SignedSSVMessage.OperatorIDs), } case spectypes.SSVPartialSignatureMsgType: psm := msg.Body.(*spectypes.PartialSignatureMessages) baseFields = []zap.Field{ - zap.Int64("signer", int64(psm.Messages[0].Signer)), // TODO: only one signer? + zap.Uint64("signer", psm.Messages[0].Signer), // TODO: only one signer? fields.Slot(psm.Slot), } } diff --git a/protocol/v2/ssv/validator/non_committee_validator.go b/protocol/v2/ssv/validator/non_committee_validator.go index bb4af784c4..aa8879b0ec 100644 --- a/protocol/v2/ssv/validator/non_committee_validator.go +++ b/protocol/v2/ssv/validator/non_committee_validator.go @@ -2,6 +2,7 @@ package validator import ( "fmt" + "github.com/ssvlabs/ssv/protocol/v2/qbft/roundtimer" "slices" "strconv" "strings" @@ -54,7 +55,7 @@ func NewCommitteeObserver(identifier convert.MessageID, opts CommitteeObserverOp Domain: opts.NetworkConfig.DomainType(), Storage: opts.Storage.Get(identifier.GetRoleType()), Network: opts.Network, - CutOffRound: specqbft.Round(specqbft.CutoffRound), + CutOffRound: roundtimer.CutOffRound, } // TODO: does the specific operator matters? diff --git a/protocol/v2/ssv/validator/validator.go b/protocol/v2/ssv/validator/validator.go index 3189d9adc6..3f20b3ddf5 100644 --- a/protocol/v2/ssv/validator/validator.go +++ b/protocol/v2/ssv/validator/validator.go @@ -11,6 +11,7 @@ import ( spectypes "github.com/ssvlabs/ssv-spec/types" "go.uber.org/zap" + "github.com/ssvlabs/ssv/utils/casts" "github.com/ssvlabs/ssv/utils/hashmap" "github.com/ssvlabs/ssv/ibft/storage" @@ -162,7 +163,7 @@ func (v *Validator) ProcessMessage(logger *zap.Logger, msg *queue.SSVMessage) er if err := qbftMsg.Validate(); err != nil { return errors.Wrap(err, "invalid qbft Message") } - logger = v.loggerForDuty(logger, spectypes.BeaconRole(messageID.GetRoleType()), phase0.Slot(qbftMsg.Height)) + logger = v.loggerForDuty(logger, casts.RunnerRoleToBeaconRole(messageID.GetRoleType()), phase0.Slot(qbftMsg.Height)) logger = logger.With(fields.Height(qbftMsg.Height)) return dutyRunner.ProcessConsensus(logger, msg.SignedSSVMessage) case spectypes.SSVPartialSignatureMsgType: @@ -172,7 +173,7 @@ func (v *Validator) ProcessMessage(logger *zap.Logger, msg *queue.SSVMessage) er if !ok { return errors.New("could not decode post consensus message from network message") } - logger = v.loggerForDuty(logger, spectypes.BeaconRole(messageID.GetRoleType()), signedMsg.Slot) + logger = v.loggerForDuty(logger, casts.RunnerRoleToBeaconRole(messageID.GetRoleType()), signedMsg.Slot) if len(msg.SignedSSVMessage.OperatorIDs) != 1 { return errors.New("PartialSignatureMessage has more than 1 signer") @@ -195,7 +196,7 @@ func (v *Validator) ProcessMessage(logger *zap.Logger, msg *queue.SSVMessage) er func (v *Validator) loggerForDuty(logger *zap.Logger, role spectypes.BeaconRole, slot phase0.Slot) *zap.Logger { logger = logger.With(fields.Slot(slot)) - if dutyID, ok := v.dutyIDs.Get(spectypes.RunnerRole(role)); ok { + if dutyID, ok := v.dutyIDs.Get(casts.BeaconRoleToRunnerRole(role)); ok { return logger.With(fields.DutyID(dutyID)) } return logger diff --git a/protocol/v2/testing/test_utils.go b/protocol/v2/testing/test_utils.go index 99130e03d9..2ae1c05dbb 100644 --- a/protocol/v2/testing/test_utils.go +++ b/protocol/v2/testing/test_utils.go @@ -48,7 +48,7 @@ func GenerateOperatorSigner(oids ...spectypes.OperatorID) ([]*rsa.PrivateKey, [] } nodes = append(nodes, &spectypes.Operator{ - OperatorID: spectypes.OperatorID(i), + OperatorID: oids[i], SSVOperatorPubKey: pubKey, }) diff --git a/protocol/v2/types/ssvshare.go b/protocol/v2/types/ssvshare.go index e5a931dab8..2b796b76bc 100644 --- a/protocol/v2/types/ssvshare.go +++ b/protocol/v2/types/ssvshare.go @@ -87,12 +87,12 @@ func (s *SSVShare) OperatorIDs() []spectypes.OperatorID { return ids } -func (s *SSVShare) HasQuorum(cnt int) bool { - return uint64(cnt) >= s.Quorum() +func (s *SSVShare) HasQuorum(cnt uint64) bool { + return cnt >= s.Quorum() } func (s *SSVShare) Quorum() uint64 { - q, _ := ComputeQuorumAndPartialQuorum(len(s.Committee)) + q, _ := ComputeQuorumAndPartialQuorum(uint64(len((s.Committee)))) return q } @@ -116,16 +116,16 @@ func ComputeClusterIDHash(address common.Address, operatorIds []uint64) []byte { return hash } -func ComputeQuorumAndPartialQuorum(committeeSize int) (quorum uint64, partialQuorum uint64) { +func ComputeQuorumAndPartialQuorum(committeeSize uint64) (quorum uint64, partialQuorum uint64) { f := ComputeF(committeeSize) return f*2 + 1, f + 1 } -func ComputeF(committeeSize int) uint64 { - return uint64(committeeSize-1) / 3 +func ComputeF(committeeSize uint64) uint64 { + return (committeeSize - 1) / 3 } -func ValidCommitteeSize(committeeSize int) bool { +func ValidCommitteeSize(committeeSize uint64) bool { f := ComputeF(committeeSize) return (committeeSize-1)%3 == 0 && f >= 1 && f <= 4 } @@ -157,8 +157,8 @@ func ComputeCommitteeID(committee []spectypes.OperatorID) spectypes.CommitteeID // Convert to bytes bytes := make([]byte, len(committee)*4) for i, v := range committee { - binary.LittleEndian.PutUint32(bytes[i*4:], uint32(v)) + binary.LittleEndian.PutUint32(bytes[i*4:], uint32(v)) // nolint:gosec } // Hash - return spectypes.CommitteeID(sha256.Sum256(bytes)) + return sha256.Sum256(bytes) } diff --git a/protocol/v2/types/ssvshare_test.go b/protocol/v2/types/ssvshare_test.go index 877989b70c..56c46397fd 100644 --- a/protocol/v2/types/ssvshare_test.go +++ b/protocol/v2/types/ssvshare_test.go @@ -84,17 +84,17 @@ func TestValidCommitteeSize(t *testing.T) { tt := []struct { name string valid bool - sizes []int + sizes []uint64 }{ { name: "valid", valid: true, - sizes: []int{4, 7, 10, 13}, + sizes: []uint64{4, 7, 10, 13}, }, { name: "invalid", valid: false, - sizes: []int{0, 1, 2, 3, 5, 6, 8, 9, 11, 12, 14, 15, 16, 17, 18, 19, -1, -4, -7}, + sizes: []uint64{0, 1, 2, 3, 5, 6, 8, 9, 11, 12, 14, 15, 16, 17, 18, 19}, }, } diff --git a/registry/storage/shares.go b/registry/storage/shares.go index 331aa4538c..46cb1c852f 100644 --- a/registry/storage/shares.go +++ b/registry/storage/shares.go @@ -105,7 +105,7 @@ func (s *storageShare) Decode(data []byte) error { if err := d.Decode(s); err != nil { return fmt.Errorf("decode storageShare: %w", err) } - s.Quorum, s.PartialQuorum = types.ComputeQuorumAndPartialQuorum(len(s.Committee)) + s.Quorum, s.PartialQuorum = types.ComputeQuorumAndPartialQuorum(uint64(len(s.Committee))) return nil } @@ -262,7 +262,7 @@ func specShareToStorageShare(share *types.SSVShare) *storageShare { PubKey: c.SharePubKey, } } - quorum, partialQuorum := types.ComputeQuorumAndPartialQuorum(len(committee)) + quorum, partialQuorum := types.ComputeQuorumAndPartialQuorum(uint64(len(committee))) stShare := &storageShare{ Share: Share{ ValidatorPubKey: share.ValidatorPubKey[:], diff --git a/registry/storage/shares_test.go b/registry/storage/shares_test.go index e2e26398bc..513cc76cf4 100644 --- a/registry/storage/shares_test.go +++ b/registry/storage/shares_test.go @@ -207,7 +207,7 @@ func generateRandomValidatorStorageShare(splitKeys map[uint64]*bls.SecretKey) (* return ibftCommittee[i].OperatorID < ibftCommittee[j].OperatorID }) - quorum, partialQuorum := ssvtypes.ComputeQuorumAndPartialQuorum(len(splitKeys)) + quorum, partialQuorum := ssvtypes.ComputeQuorumAndPartialQuorum(uint64(len(splitKeys))) return &storageShare{ Share: Share{ diff --git a/scripts/differ/parser.go b/scripts/differ/parser.go index 9c1d9ed379..841ce8f0f0 100644 --- a/scripts/differ/parser.go +++ b/scripts/differ/parser.go @@ -85,7 +85,9 @@ func (p *Parser) addElement(n ast.Node) bool { // Get the code. var buf bytes.Buffer - printer.Fprint(&buf, p.fset, n) + if err := printer.Fprint(&buf, p.fset, n); err != nil { + log.Fatal(err) + } code := regexpRemains.ReplaceAllString(buf.String(), "") // Get the file. diff --git a/scripts/spec-alignment/differ.config.yaml b/scripts/spec-alignment/differ.config.yaml index d4c4f3cb63..3c30ab9a4d 100644 --- a/scripts/spec-alignment/differ.config.yaml +++ b/scripts/spec-alignment/differ.config.yaml @@ -1,4 +1,4 @@ -ApprovedChanges: ["50e5bb7eda99594e", "870a3a66aeccd737","4e22a08543b079b","56ceb03cd44ff702","188adfe8914e04c1","2438f9c5b82b69a3","1a716ee3bdb3170","90b166f78390af18","68219b82a1d9d829","c4c4caa5d0938b85","dfe99ce1d27b6cb1","35f5dab1f128d193","9a3973b64d7e8932","f33f07301a770d03","3e9e0dddfad3b302","d4fef6512374c1f5","b49f54cb45787e4b","59b2375130aef5df","f094cd0460432170","8e51881e527dd603","a7d6d58d9fa06379","1d124224ca4d0fe3","39ea06bfd1477d2d","7e2550bab51f22b2","87ebd29bd49fc52f","ef39dd5223e0d080","fe14e7f0503ea188","6146023d4d5708a2","aebb8e4348b6d667","973a2e6704dbf3","fb4cac598a68c592","257c7eb81d6eb245","2a8e94fe037e13fd","5e7eb878de54eec6","960a9c64cd4ec93c","57dfd255520bd849","ec333ff8a708db69","1cc1ff39ad91ee69","5714652b88e2d44f","7a53b3b037c56325","8c02ef1964464c30","19a268910a20da3d","af6e01ed565029f3","318b5169ac4dabb6","372c6b332e8ba699","c0d8a364c0db855a","4287381be4fb1841","b1614afc1da7794f","c214975412f3fd7","8bbf7eba3fa0cf7e","8e4ec8debe331b36","7a671d8fcefc3793","e2b0e9c6454c1c08","6707ecfefa5fec21","d5a7389d730464f1","8dfae3b3223d2de0","a81c092c985de728","968df5082c727ed6","9e53c73ee60b1cc2","9d265e99dd31d4f5","a34619e078d2e42f","17e8cec4f0625d53","e913f373aa88f333","cfc1e05c372d88dc","e5de6901d78b8833","57c1885b43dd8d19","e8a49856a5edd893","22ea21d10a2f861c","954e4fce01631c4e","108b9575f7c1d4bc","1f8d076449068f64","5a7ad98296703f6","159536003eeddac8","8ca8f82e67ddd3dd","16ebe47404323cc1","48bfe5cf1e578b47","dd83182b693a7216","308d21d9830f7047","6dde03147e012b1a","730c3e5e59393b7d","5b44a4b425ecc397","df5debc50ec8babc","92a41554b2910bb8","c36c680554dde59f","447feaa5cdc1a010","fda90c61f44cb149","cdbb4930eced584c","274336ec1127e6c0","2a496f5b3ad542d2","6b395912dde33b0e","cac56ec14994216b","8850900b5d9bcc65","15e7706486c6359e","cc22f28953b787ea","3bad6ae11596a574","8f84422a240d889c","5b265432dfbbaac7","43794bf5953db193","7975821460ebe1e7","173c505e12aabb8f","47ee0d148148a56f","8cc38593ebe049b6","bda3aec7157b095a","248712911696a851","f4d9c910f1dbaef7","1a2146fcad37acb8","b0b146f9bdab64b6","edfd442b4d725fbb","122f053573538a32","d720d714a20833e1", "f9c984e71b685f9b","8c6b4fee5a4c13ce","c0a8d2019a2c30d5", "717bef26105c733f","2f70630c27062353","2f70337ba7566a69","dd607a44e1341e6b","5210501625ac3de5","f786bf475b5085aa","18a66ed6e613d9c1","e8943e7741f6843d","276a489bd5a00032","ba3bba59f10bf6b","3c50ce0c8089d871","89ee72f6c610ab84","c92b95a85da2cb11","927ea6aed3f98f20","9338904026a0ce37","9683cfa19dc544a3","4d3fa2b8dfcb5f5b", "f19e9a2b295bcfb3", "b10199b2de6f03b8", "1afc17e358f9ca79","4b58762c0b433442","d293ec1bc61bb707","3e88c3b49d093605","4890ff80c88cc41d","5227ff3a225dd20d","81a60407a3a0ba80","db2ad807eb66254a","d308bd7c553ccdcf","bdaf172971637cbe","6ade9202843071fe","2fe8e14083997744","19c9a5362d1e1d3a","5956f803d239f178","92c55a4548a8b760","9a95524213bccfff","2f51a7338b86c229","e96966a281d74505","3ee479b9cbbc3a1d","82b392ba39c6c594","b9d2404e5c570019","24f528d85fb021f2","fe9609a785305d81","b0934079dcd986cc","a9c520a19b26049","d19a9403fd732d94","74a928f5dcb2fdd9","cbbfdb5e68cdac80","10e39d2ceda91f34","f99a004cf6697875","8fa5e8ebf7d223ec","6c80c145ba705243","fbabbc90d0b4178a","b110cba51df9f8d2","c4ff2ed3d20dc419","9295a5bb10efcec7","ab56ea44a75f898a","ff51ef26ab53ba58","df3771e2589008f9","106e5689655bcfc6","f90e0fb6883bff93","667656095cec39ee"] +ApprovedChanges: ["50e5bb7eda99594e", "870a3a66aeccd737","4e22a08543b079b","56ceb03cd44ff702","188adfe8914e04c1","2438f9c5b82b69a3","1a716ee3bdb3170","90b166f78390af18","68219b82a1d9d829","c4c4caa5d0938b85","dfe99ce1d27b6cb1","35f5dab1f128d193","9a3973b64d7e8932","f33f07301a770d03","3e9e0dddfad3b302","d4fef6512374c1f5","b49f54cb45787e4b","59b2375130aef5df","f094cd0460432170","8e51881e527dd603","a7d6d58d9fa06379","1d124224ca4d0fe3","39ea06bfd1477d2d","7e2550bab51f22b2","87ebd29bd49fc52f","ef39dd5223e0d080","fe14e7f0503ea188","6146023d4d5708a2","aebb8e4348b6d667","973a2e6704dbf3","fb4cac598a68c592","257c7eb81d6eb245","2a8e94fe037e13fd","5e7eb878de54eec6","960a9c64cd4ec93c","57dfd255520bd849","ec333ff8a708db69","1cc1ff39ad91ee69","5714652b88e2d44f","7a53b3b037c56325","8c02ef1964464c30","19a268910a20da3d","af6e01ed565029f3","318b5169ac4dabb6","372c6b332e8ba699","c0d8a364c0db855a","4287381be4fb1841","b1614afc1da7794f","c214975412f3fd7","8bbf7eba3fa0cf7e","8e4ec8debe331b36","7a671d8fcefc3793","e2b0e9c6454c1c08","6707ecfefa5fec21","d5a7389d730464f1","8dfae3b3223d2de0","a81c092c985de728","968df5082c727ed6","9e53c73ee60b1cc2","9d265e99dd31d4f5","a34619e078d2e42f","17e8cec4f0625d53","e913f373aa88f333","cfc1e05c372d88dc","e5de6901d78b8833","57c1885b43dd8d19","e8a49856a5edd893","22ea21d10a2f861c","954e4fce01631c4e","108b9575f7c1d4bc","1f8d076449068f64","5a7ad98296703f6","159536003eeddac8","8ca8f82e67ddd3dd","16ebe47404323cc1","48bfe5cf1e578b47","dd83182b693a7216","308d21d9830f7047","6dde03147e012b1a","730c3e5e59393b7d","5b44a4b425ecc397","df5debc50ec8babc","92a41554b2910bb8","c36c680554dde59f","447feaa5cdc1a010","fda90c61f44cb149","cdbb4930eced584c","274336ec1127e6c0","2a496f5b3ad542d2","6b395912dde33b0e","cac56ec14994216b","8850900b5d9bcc65","15e7706486c6359e","cc22f28953b787ea","3bad6ae11596a574","8f84422a240d889c","5b265432dfbbaac7","43794bf5953db193","7975821460ebe1e7","173c505e12aabb8f","47ee0d148148a56f","8cc38593ebe049b6","bda3aec7157b095a","248712911696a851","f4d9c910f1dbaef7","1a2146fcad37acb8","b0b146f9bdab64b6","edfd442b4d725fbb","122f053573538a32","d720d714a20833e1", "f9c984e71b685f9b","8c6b4fee5a4c13ce","c0a8d2019a2c30d5", "717bef26105c733f","2f70630c27062353","2f70337ba7566a69","dd607a44e1341e6b","5210501625ac3de5","f786bf475b5085aa","18a66ed6e613d9c1","e8943e7741f6843d","276a489bd5a00032","ba3bba59f10bf6b","3c50ce0c8089d871","89ee72f6c610ab84","c92b95a85da2cb11","927ea6aed3f98f20","9338904026a0ce37","9683cfa19dc544a3","4d3fa2b8dfcb5f5b", "f19e9a2b295bcfb3", "b10199b2de6f03b8", "1afc17e358f9ca79","4b58762c0b433442","d293ec1bc61bb707","3e88c3b49d093605","4890ff80c88cc41d","5227ff3a225dd20d","81a60407a3a0ba80","db2ad807eb66254a","d308bd7c553ccdcf","bdaf172971637cbe","6ade9202843071fe","2fe8e14083997744","19c9a5362d1e1d3a","5956f803d239f178","92c55a4548a8b760","9a95524213bccfff","2f51a7338b86c229","e96966a281d74505","3ee479b9cbbc3a1d","82b392ba39c6c594","b9d2404e5c570019","24f528d85fb021f2","fe9609a785305d81","b0934079dcd986cc","a9c520a19b26049","d19a9403fd732d94","74a928f5dcb2fdd9","cbbfdb5e68cdac80","10e39d2ceda91f34","f99a004cf6697875","8fa5e8ebf7d223ec","6c80c145ba705243","fbabbc90d0b4178a","ab0c7f24e551ca6","af38a11cb8682c75","b110cba51df9f8d2","c4ff2ed3d20dc419","9295a5bb10efcec7","ab56ea44a75f898a","ff51ef26ab53ba58","df3771e2589008f9","106e5689655bcfc6","f90e0fb6883bff93","667656095cec39ee","9a5597af260c748a"] IgnoredIdentifiers: - logger diff --git a/scripts/spec-alignment/genesis_differ.config.yaml b/scripts/spec-alignment/genesis_differ.config.yaml index 2e890c45b6..8c46ba8ac9 100644 --- a/scripts/spec-alignment/genesis_differ.config.yaml +++ b/scripts/spec-alignment/genesis_differ.config.yaml @@ -1,4 +1,4 @@ -ApprovedChanges: ["52b93267ba812308","9f2881f9e89b4c3","f8718ef9598a2d28","ea4da0c78bc1e930","11481543a56b03e7","4bc55d173976f499","5a326429bd7d816a","57938492d36e5b72","ea83b3555f29e44e","39a395cc56c381d8","2092a46a009de5e9","f9e12bb821abda59","74490095cad1f871","fef6a577794897e9","e243efb1fef8baca","b612f4f4bee5726c","b4072ece06d92c84","487d349a6296651e","1329fd2f0f7101e5","6ea163caa000821c","cb2a3fac03c9f70d","c155c7005d298b8a","5462556ab33327ae","66591f5d3e9c299d","ef530512222fa3a3","54f7ee00c5223d56","136792991a713119","519dec1f394a29bb","c16537938b23bb1c","930f8003cc73658a","b4d4b7c288d15580","8e871e3dc302502c","264f6c3cb6c044e","73b442121276436f","a5d665260b9545e7","e76da25dcc1b8b7b","3021b027e65343dc","37abca362396de40","10331350bdd5cea5","ff66465e82a0bce","7008ba0e5fb3bc50","17d86fc521251084","60ee89aed3dca274","cfb5a31338393004","774c67a1117bb600","bbbac3fd539c9da","4120ef6224cd7653","c13c14ac8b912a99","e34eb83c1de17e7b","d60440779e512dda","8b474f07634c3b5b","ac42b9ed129f763c","67809ff9e1f78fba","436d37b16e59e851","d201c716184904d6","422221ab59ac4658","30ed9a822232b7e1","c08c6d84582b86c1","c07315929c5bfdae","751997d95ea9340","7715acc5b4c5aa2","14d6cdfdf92136fc","c9db895746d32d2","a0a0164bd2ecb327","c0cb3984d0a20d8","1c8beb7d60ffa18a","b44005e951042d3","45749213deaece88","6afb57c28a55854c","5619c6b724070584","81385e7b399b3235","856eb69df47300bc","68ab7316969c38b","c8f63fe574c9cd3","a1dd0a169df78d67","4bb11f08323af914","466839f492add207","6c3507bea504fcc","560bb093d1aea569","a13eb5088003f50b","9f5f0eff2dca5e9", "397220931cab52bc","453245a906210497","1eb92714f465d122", "2015d5566f6182e1","9f0799ecd4426e43","20a0cfb49029370f","b5ae2491e369931a","94800037492ba19a","57f89a48ccc5bdb0","a825ac16288e518f","1a8754cea558330e","837449174a662384", "eb4770deec3d69ae","88c54a52b5c156ec","7b39050170e98fbe"] +ApprovedChanges: ["52b93267ba812308","9f2881f9e89b4c3","f8718ef9598a2d28","ea4da0c78bc1e930","11481543a56b03e7","4bc55d173976f499","5a326429bd7d816a","57938492d36e5b72","ea83b3555f29e44e","39a395cc56c381d8","2092a46a009de5e9","f9e12bb821abda59","74490095cad1f871","fef6a577794897e9","e243efb1fef8baca","b612f4f4bee5726c","b4072ece06d92c84","487d349a6296651e","1329fd2f0f7101e5","6ea163caa000821c","cb2a3fac03c9f70d","c155c7005d298b8a","5462556ab33327ae","66591f5d3e9c299d","ef530512222fa3a3","54f7ee00c5223d56","136792991a713119","519dec1f394a29bb","c16537938b23bb1c","930f8003cc73658a","b4d4b7c288d15580","8e871e3dc302502c","264f6c3cb6c044e","73b442121276436f","a5d665260b9545e7","e76da25dcc1b8b7b","3021b027e65343dc","37abca362396de40","10331350bdd5cea5","ff66465e82a0bce","7008ba0e5fb3bc50","17d86fc521251084","60ee89aed3dca274","cfb5a31338393004","774c67a1117bb600","bbbac3fd539c9da","4120ef6224cd7653","c13c14ac8b912a99","e34eb83c1de17e7b","d60440779e512dda","8b474f07634c3b5b","ac42b9ed129f763c","67809ff9e1f78fba","436d37b16e59e851","d201c716184904d6","422221ab59ac4658","30ed9a822232b7e1","c08c6d84582b86c1","c07315929c5bfdae","751997d95ea9340","7715acc5b4c5aa2","14d6cdfdf92136fc","c9db895746d32d2","a0a0164bd2ecb327","c0cb3984d0a20d8","1c8beb7d60ffa18a","b44005e951042d3","45749213deaece88","6afb57c28a55854c","5619c6b724070584","81385e7b399b3235","856eb69df47300bc","68ab7316969c38b","c8f63fe574c9cd3","a1dd0a169df78d67","4bb11f08323af914","466839f492add207","6c3507bea504fcc","560bb093d1aea569","a13eb5088003f50b","9f5f0eff2dca5e9", "397220931cab52bc","453245a906210497","1eb92714f465d122", "2015d5566f6182e1","9f0799ecd4426e43","20a0cfb49029370f","b5ae2491e369931a","94800037492ba19a","57f89a48ccc5bdb0","a825ac16288e518f","1a8754cea558330e","837449174a662384", "eb4770deec3d69ae","88c54a52b5c156ec","7b39050170e98fbe","a94f7bc050a7c5e0"] IgnoredIdentifiers: - logger diff --git a/utils/boot_node/node.go b/utils/boot_node/node.go index c1735c3eb2..dabf348e9d 100644 --- a/utils/boot_node/node.go +++ b/utils/boot_node/node.go @@ -30,8 +30,8 @@ var SSVProtocolID = [6]byte{'s', 's', 'v', 'd', 'v', '5'} type Options struct { PrivateKey string `yaml:"PrivateKey" env:"BOOT_NODE_PRIVATE_KEY" env-description:"boot node private key (default will generate new)"` ExternalIP string `yaml:"ExternalIP" env:"BOOT_NODE_EXTERNAL_IP" env-description:"Override boot node's external IP"` - TCPPort int `yaml:"TcpPort" env:"TCP_PORT" env-default:"5000" env-description:"TCP port for p2p transport"` - UDPPort int `yaml:"UdpPort" env:"UDP_PORT" env-default:"4000" env-description:"UDP port for discovery"` + TCPPort uint16 `yaml:"TcpPort" env:"TCP_PORT" env-default:"5000" env-description:"TCP port for p2p transport"` + UDPPort uint16 `yaml:"UdpPort" env:"UDP_PORT" env-default:"4000" env-description:"UDP port for discovery"` DbPath string `yaml:"DbPath" env:"BOOT_NODE_DB_PATH" env-default:"/data/bootnode" env-description:"Path to the boot node's database"` Network string `yaml:"Network" env:"NETWORK" env-default:"mainnet"` } @@ -45,10 +45,10 @@ type Node interface { // bootNode implements Node interface type bootNode struct { privateKey string - discv5port int + discv5port uint16 forkVersion []byte externalIP string - tcpPort int + tcpPort uint16 dbPath string network networkconfig.NetworkConfig } @@ -138,7 +138,7 @@ func (n *bootNode) Start(ctx context.Context, logger *zap.Logger) error { return nil } -func (n *bootNode) createListener(logger *zap.Logger, ipAddr string, port int, cfg discover.Config) *discover.UDPv5 { +func (n *bootNode) createListener(logger *zap.Logger, ipAddr string, port uint16, cfg discover.Config) *discover.UDPv5 { ip := net.ParseIP(ipAddr) if ip.To4() == nil { logger.Fatal("IPV4 address not provided", fields.Address(ipAddr)) @@ -157,7 +157,7 @@ func (n *bootNode) createListener(logger *zap.Logger, ipAddr string, port int, c } udpAddr := &net.UDPAddr{ IP: bindIP, - Port: port, + Port: int(port), } conn, err := net.ListenUDP(networkVersion, udpAddr) if err != nil { @@ -175,7 +175,7 @@ func (n *bootNode) createListener(logger *zap.Logger, ipAddr string, port int, c return network } -func (n *bootNode) createLocalNode(logger *zap.Logger, privKey *ecdsa.PrivateKey, ipAddr net.IP, port int) (*enode.LocalNode, error) { +func (n *bootNode) createLocalNode(logger *zap.Logger, privKey *ecdsa.PrivateKey, ipAddr net.IP, port uint16) (*enode.LocalNode, error) { db, err := enode.OpenDB(filepath.Join(n.dbPath, "enode")) if err != nil { return nil, errors.Wrap(err, "Could not open node's peer database") @@ -211,7 +211,7 @@ func (n *bootNode) createLocalNode(logger *zap.Logger, privKey *ecdsa.PrivateKey localNode := enode.NewLocalNode(db, privKey) localNode.Set(enr.WithEntry("ssv", true)) localNode.SetFallbackIP(external) - localNode.SetFallbackUDP(port) + localNode.SetFallbackUDP(int(port)) ipEntry := enr.IP(external) udpEntry := enr.UDP(port) diff --git a/utils/casts/casts.go b/utils/casts/casts.go new file mode 100644 index 0000000000..38aa186519 --- /dev/null +++ b/utils/casts/casts.go @@ -0,0 +1,44 @@ +package casts + +import ( + "fmt" + "math" + "time" + + spectypes "github.com/ssvlabs/ssv-spec/types" + + "github.com/ssvlabs/ssv/exporter/convert" +) + +var ( + ErrNegativeTime = fmt.Errorf("time can't be negative") + ErrMaxDurationOverflow = fmt.Errorf("duration can't exceed max int64") +) + +// DurationFromUint64 converts uint64 to time.Duration +func DurationFromUint64(t uint64) time.Duration { + if t > math.MaxInt64 { + return time.Duration(math.MaxInt64) // todo: error handling refactor + } + return time.Duration(t) // #nosec G115 +} + +func BeaconRoleToConvertRole(beaconRole spectypes.BeaconRole) convert.RunnerRole { + return convert.RunnerRole(beaconRole) // #nosec G115 +} + +func BeaconRoleToRunnerRole(beaconRole spectypes.BeaconRole) spectypes.RunnerRole { + return spectypes.RunnerRole(beaconRole) // #nosec G115 +} + +func RunnerRoleToBeaconRole(role spectypes.RunnerRole) spectypes.BeaconRole { + return spectypes.BeaconRole(role) // #nosec G115 +} + +// DurationToUint64 returns error if duration is negative and converts time.Duration to uint64 safe otherwise +func DurationToUint64(t time.Duration) (uint64, error) { + if t < 0 { + return 0, ErrNegativeTime + } + return uint64(t), nil // #nosec G115 +}