Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
fca0876
beacon/goclient: get beacon config from beacon node
nkryuchkov Apr 16, 2025
5253cca
Merge branch 'networkconfig-extract-beacon-params' into networkconfig…
nkryuchkov Apr 16, 2025
c3f3527
use beacon config obtained from beacon node
nkryuchkov Apr 16, 2025
e57ef03
log config as JSON
nkryuchkov Apr 17, 2025
3cdda27
networkconfig: CLI for custom SSV config generation
nkryuchkov Apr 17, 2025
17eb427
implement JSON marshaling and YAML marshaling/unmarshaling
nkryuchkov Apr 17, 2025
cf5db78
remove TotalEthereumValidators
nkryuchkov Apr 17, 2025
72f4d8d
simplify marshaling/unmarshaling logic
nkryuchkov Apr 17, 2025
1337765
fix markdown formatting
nkryuchkov Apr 17, 2025
e226819
use yaml@v3
nkryuchkov Apr 17, 2025
b91c135
add tests
nkryuchkov Apr 17, 2025
a286f15
simplify unmarshaling
nkryuchkov Apr 17, 2025
65acd9b
delete a comment
nkryuchkov Apr 17, 2025
7dd8ea4
Merge branch 'networkconfig-extract-beacon-params' into networkconfig…
nkryuchkov Apr 17, 2025
d5dea5a
use Stringer to log node
nkryuchkov Apr 17, 2025
4fc30f2
guard beacon config reads with mutex
nkryuchkov Apr 17, 2025
c04d2b9
add a timeout log
nkryuchkov Apr 17, 2025
c2e2f8f
delete hardcoded beacon configs
nkryuchkov Apr 19, 2025
be8fbb7
Revert "delete hardcoded beacon configs"
nkryuchkov Apr 19, 2025
b43d3e5
networkconfig: make hardcoded values configurable
nkryuchkov Apr 19, 2025
ae1a6cb
Merge branch 'networkconfig-generate-ssv' into networkconfig-make-har…
nkryuchkov Apr 19, 2025
b1d22f0
Merge branch 'networkconfig-extract-beacon-params' into networkconfig…
nkryuchkov Apr 24, 2025
e8d1fa2
fix issues after merging
nkryuchkov Apr 24, 2025
301fe46
code review comments
nkryuchkov Apr 24, 2025
c93cc43
Merge branch 'networkconfig-from-beacon-node' into networkconfig-gene…
nkryuchkov Apr 24, 2025
7be669a
Merge branch 'networkconfig-generate-ssv' into networkconfig-make-har…
nkryuchkov Apr 24, 2025
ebde306
fix issues after merging
nkryuchkov Apr 24, 2025
bec420c
delete outer metrics for genesisForClient
nkryuchkov Apr 24, 2025
d1fd692
rewrite modulo calculation
nkryuchkov Apr 24, 2025
9947640
code review comments
nkryuchkov Apr 24, 2025
a22b256
unexport supportedSSVConfigs
nkryuchkov Apr 24, 2025
34f8fc0
revert the modulo calculation
nkryuchkov Apr 24, 2025
06d5f8a
add EpochDuration mock
nkryuchkov Apr 25, 2025
5f8dd7e
G115
nkryuchkov Apr 25, 2025
36a7a31
fill missing fields in configs
nkryuchkov Apr 25, 2025
70ce02e
add a comment about eth spec
nkryuchkov Apr 25, 2025
5ccf73e
fix error text
nkryuchkov Apr 25, 2025
94aec3b
use genesis validators root from config in computeVoluntaryExitDomain
nkryuchkov Apr 25, 2025
f8af8b0
Merge branch 'networkconfig-extract-beacon-params' into networkconfig…
nkryuchkov Apr 28, 2025
aa5d378
Merge branch 'networkconfig-from-beacon-node' into networkconfig-gene…
nkryuchkov Apr 28, 2025
53cc7c3
Merge branch 'networkconfig-generate-ssv' into networkconfig-make-har…
nkryuchkov Apr 28, 2025
144e380
fix linter
nkryuchkov Apr 30, 2025
95279d0
Merge branch 'networkconfig-generate-ssv' into networkconfig-make-har…
nkryuchkov Apr 30, 2025
a04d173
Merge branch 'networkconfig-extract-beacon-params' into networkconfig…
nkryuchkov May 12, 2025
5183f8b
fix a typo
nkryuchkov May 12, 2025
8b4d726
remove redundant comments
nkryuchkov May 12, 2025
a91171b
Merge branch 'networkconfig-extract-beacon-params' into networkconfig…
nkryuchkov May 21, 2025
74167bd
Merge branch 'networkconfig-from-beacon-node' into networkconfig-gene…
nkryuchkov May 21, 2025
3ec364e
fix a context bug
nkryuchkov May 22, 2025
180db70
Merge branch 'networkconfig-from-beacon-node' into networkconfig-gene…
nkryuchkov May 22, 2025
3a1cc0d
Merge branch 'networkconfig-generate-ssv' into networkconfig-make-har…
nkryuchkov May 23, 2025
5478ec1
fix issues after merging
nkryuchkov May 23, 2025
f790d99
pass network config name
nkryuchkov May 26, 2025
ae9dde4
Merge branch 'networkconfig-extract-beacon-params' into networkconfig…
nkryuchkov May 26, 2025
6d720fe
Merge branch 'networkconfig-from-beacon-node' into networkconfig-gene…
nkryuchkov May 26, 2025
1eaef3d
Merge branch 'networkconfig-generate-ssv' into networkconfig-make-har…
nkryuchkov May 26, 2025
28bf5ce
Merge branch 'networkconfig-extract-beacon-params' into networkconfig…
nkryuchkov May 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions beacon/goclient/aggregator.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
gc.waitToSlotTwoThirds(slot)

// differ from spec because we need to subscribe to subnet
isAggregator := isAggregator(committeeLength, slotSig)
isAggregator := gc.isAggregator(committeeLength, slotSig)

Check warning on line 33 in beacon/goclient/aggregator.go

View check run for this annotation

Codecov / codecov/patch

beacon/goclient/aggregator.go#L33

Added line #L33 was not covered by tests
if !isAggregator {
return nil, DataVersionNil, fmt.Errorf("validator is not an aggregator")
}
Expand Down Expand Up @@ -188,8 +188,8 @@
// committee = get_beacon_committee(state, slot, index)
// modulo = max(1, len(committee) // TARGET_AGGREGATORS_PER_COMMITTEE)
// return bytes_to_uint64(hash(slot_signature)[0:8]) % modulo == 0
func isAggregator(committeeCount uint64, slotSig []byte) bool {
modulo := committeeCount / TargetAggregatorsPerCommittee
func (gc *GoClient) isAggregator(committeeCount uint64, slotSig []byte) bool {
modulo := committeeCount / gc.beaconConfig.TargetAggregatorsPerCommittee

Check warning on line 192 in beacon/goclient/aggregator.go

View check run for this annotation

Codecov / codecov/patch

beacon/goclient/aggregator.go#L191-L192

Added lines #L191 - L192 were not covered by tests
if modulo == 0 {
// Modulo must be at least 1.
modulo = 1
Expand All @@ -202,8 +202,8 @@
// waitToSlotTwoThirds waits until two-third of the slot has transpired (SECONDS_PER_SLOT * 2 / 3 seconds after slot start time)
func (gc *GoClient) waitToSlotTwoThirds(slot phase0.Slot) {
config := gc.getBeaconConfig()
oneThird := config.SlotDuration / 3 /* one third of slot duration */
finalTime := config.GetSlotStartTime(slot).Add(2 * oneThird)
oneInterval := config.IntervalDuration()
finalTime := config.GetSlotStartTime(slot).Add(2 * oneInterval)

Check warning on line 206 in beacon/goclient/aggregator.go

View check run for this annotation

Codecov / codecov/patch

beacon/goclient/aggregator.go#L205-L206

Added lines #L205 - L206 were not covered by tests
wait := time.Until(finalTime)
if wait <= 0 {
return
Expand Down
10 changes: 2 additions & 8 deletions beacon/goclient/signing.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,10 @@ func (gc *GoClient) computeVoluntaryExitDomain(ctx context.Context) (phase0.Doma
}

forkData := &phase0.ForkData{
CurrentVersion: forkVersion,
CurrentVersion: forkVersion,
GenesisValidatorsRoot: gc.getBeaconConfig().GenesisValidatorsRoot,
}

genesis, err := gc.Genesis(ctx)
if err != nil {
return phase0.Domain{}, fmt.Errorf("failed to obtain genesis response: %w", err)
}

forkData.GenesisValidatorsRoot = genesis.GenesisValidatorsRoot

root, err := forkData.HashTreeRoot()
if err != nil {
return phase0.Domain{}, fmt.Errorf("failed to calculate signature domain, err: %w", err)
Expand Down
93 changes: 83 additions & 10 deletions beacon/goclient/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,14 @@
)

const (
DefaultSlotDuration = 12 * time.Second
DefaultSlotsPerEpoch = uint64(32)
DefaultSlotDuration = 12 * time.Second
DefaultSlotsPerEpoch = uint64(32)
DefaultEpochsPerSyncCommitteePeriod = uint64(256)
DefaultSyncCommitteeSize = uint64(512)
DefaultSyncCommitteeSubnetCount = uint64(4)
DefaultTargetAggregatorsPerSyncSubcommittee = uint64(16)
DefaultTargetAggregatorsPerCommittee = uint64(16)
DefaultIntervalsPerSlot = uint64(3)
)

// BeaconConfig returns the network Beacon configuration
Expand All @@ -39,7 +45,7 @@

networkNameRaw, ok := specResponse["CONFIG_NAME"]
if !ok {
return networkconfig.BeaconConfig{}, fmt.Errorf("config name not known by chain")
return networkconfig.BeaconConfig{}, fmt.Errorf("config name wasn't found in beacon node response")

Check warning on line 48 in beacon/goclient/spec.go

View check run for this annotation

Codecov / codecov/patch

beacon/goclient/spec.go#L48

Added line #L48 was not covered by tests
}

networkName, ok := networkNameRaw.(string)
Expand All @@ -52,7 +58,7 @@
if slotDurationDecoded, ok := slotDurationRaw.(time.Duration); ok {
slotDuration = slotDurationDecoded
} else {
gc.log.Warn("seconds per slot not known by chain, using default value",
gc.log.Warn("seconds per slot wasn't found in beacon node response, using default value",

Check warning on line 61 in beacon/goclient/spec.go

View check run for this annotation

Codecov / codecov/patch

beacon/goclient/spec.go#L61

Added line #L61 was not covered by tests
zap.Any("value", slotDuration))
}
}
Expand All @@ -62,23 +68,90 @@
if slotsPerEpochDecoded, ok := slotsPerEpochRaw.(uint64); ok {
slotsPerEpoch = slotsPerEpochDecoded
} else {
gc.log.Warn("slots per epoch not known by chain, using default value",
gc.log.Warn("slots per epoch wasn't found in beacon node response, using default value",

Check warning on line 71 in beacon/goclient/spec.go

View check run for this annotation

Codecov / codecov/patch

beacon/goclient/spec.go#L71

Added line #L71 was not covered by tests
zap.Uint64("value", slotsPerEpoch))
}
}

epochsPerSyncCommitteePeriod := DefaultEpochsPerSyncCommitteePeriod
if epochsPerSyncCommitteePeriodRaw, ok := specResponse["EPOCHS_PER_SYNC_COMMITTEE_PERIOD"]; ok {
Comment thread
nkryuchkov marked this conversation as resolved.
if epochsPerSyncCommitteePeriodDecoded, ok := epochsPerSyncCommitteePeriodRaw.(uint64); ok {
epochsPerSyncCommitteePeriod = epochsPerSyncCommitteePeriodDecoded
} else {
gc.log.Warn("epochs per sync committee wasn't found in beacon node response, using default value",
zap.Any("value", epochsPerSyncCommitteePeriod))
}

Check warning on line 83 in beacon/goclient/spec.go

View check run for this annotation

Codecov / codecov/patch

beacon/goclient/spec.go#L81-L83

Added lines #L81 - L83 were not covered by tests
}

syncCommitteeSize := DefaultSyncCommitteeSize
if syncCommitteeSizeRaw, ok := specResponse["SYNC_COMMITTEE_SIZE"]; ok {
if syncCommitteeSizeDecoded, ok := syncCommitteeSizeRaw.(uint64); ok {
syncCommitteeSize = syncCommitteeSizeDecoded
} else {
gc.log.Warn("sync committee size wasn't found in beacon node response, using default value",
zap.Any("value", syncCommitteeSize))
}

Check warning on line 93 in beacon/goclient/spec.go

View check run for this annotation

Codecov / codecov/patch

beacon/goclient/spec.go#L91-L93

Added lines #L91 - L93 were not covered by tests
}

targetAggregatorsPerCommittee := DefaultTargetAggregatorsPerCommittee
if targetAggregatorsPerCommitteeRaw, ok := specResponse["TARGET_AGGREGATORS_PER_COMMITTEE"]; ok {
if targetAggregatorsPerCommitteeDecoded, ok := targetAggregatorsPerCommitteeRaw.(uint64); ok {
targetAggregatorsPerCommittee = targetAggregatorsPerCommitteeDecoded
} else {
gc.log.Warn("target aggregators per committee wasn't found in beacon node response, using default value",
zap.Any("value", targetAggregatorsPerCommittee))
}

Check warning on line 103 in beacon/goclient/spec.go

View check run for this annotation

Codecov / codecov/patch

beacon/goclient/spec.go#L101-L103

Added lines #L101 - L103 were not covered by tests
}

targetAggregatorsPerSyncSubcommittee := DefaultTargetAggregatorsPerSyncSubcommittee
if targetAggregatorsPerSyncSubcommitteeRaw, ok := specResponse["TARGET_AGGREGATORS_PER_SYNC_SUBCOMMITTEE"]; ok {
if targetAggregatorsPerSyncSubcommitteeDecoded, ok := targetAggregatorsPerSyncSubcommitteeRaw.(uint64); ok {
targetAggregatorsPerSyncSubcommittee = targetAggregatorsPerSyncSubcommitteeDecoded
} else {
gc.log.Warn("target aggregators per sync subcommittee wasn't found in beacon node response, using default value",
zap.Any("value", targetAggregatorsPerSyncSubcommittee))
}

Check warning on line 113 in beacon/goclient/spec.go

View check run for this annotation

Codecov / codecov/patch

beacon/goclient/spec.go#L111-L113

Added lines #L111 - L113 were not covered by tests
}

intervalsPerSlot := DefaultIntervalsPerSlot
if intervalsPerSlotRaw, ok := specResponse["INTERVALS_PER_SLOT"]; ok {
Comment thread
oleg-ssvlabs marked this conversation as resolved.
if intervalsPerSlotDecoded, ok := intervalsPerSlotRaw.(uint64); ok {
intervalsPerSlot = intervalsPerSlotDecoded
} else {
gc.log.Warn("intervals per slot wasn't found in beacon node response, using default value",
zap.Any("value", intervalsPerSlot))
}

Check warning on line 123 in beacon/goclient/spec.go

View check run for this annotation

Codecov / codecov/patch

beacon/goclient/spec.go#L121-L123

Added lines #L121 - L123 were not covered by tests
}

syncCommitteeSubnetCount := DefaultSyncCommitteeSubnetCount
if syncCommitteeSubnetCountRaw, ok := specResponse["SYNC_COMMITTEE_SUBNET_COUNT"]; ok {
if syncCommitteeSubnetCountDecoded, ok := syncCommitteeSubnetCountRaw.(uint64); ok {
syncCommitteeSubnetCount = syncCommitteeSubnetCountDecoded
} else {
gc.log.Warn("sync committee subnet count wasn't found in beacon node response, using default value",
zap.Any("value", syncCommitteeSubnetCount))
}

Check warning on line 133 in beacon/goclient/spec.go

View check run for this annotation

Codecov / codecov/patch

beacon/goclient/spec.go#L131-L133

Added lines #L131 - L133 were not covered by tests
}

genesisResponse, err := genesisForClient(ctx, gc.log, client)
if err != nil {
gc.log.Error(clResponseErrMsg, zap.String("api", "Genesis"), zap.Error(err))
return networkconfig.BeaconConfig{}, fmt.Errorf("failed to obtain genesis response: %w", err)
}

beaconConfig := networkconfig.BeaconConfig{
BeaconName: networkName,
SlotDuration: slotDuration,
SlotsPerEpoch: slotsPerEpoch,
ForkVersion: genesisResponse.GenesisForkVersion,
GenesisTime: genesisResponse.GenesisTime,
BeaconName: networkName,
SlotDuration: slotDuration,
SlotsPerEpoch: slotsPerEpoch,
EpochsPerSyncCommitteePeriod: epochsPerSyncCommitteePeriod,
SyncCommitteeSize: syncCommitteeSize,
SyncCommitteeSubnetCount: syncCommitteeSubnetCount,
TargetAggregatorsPerSyncSubcommittee: targetAggregatorsPerSyncSubcommittee,
TargetAggregatorsPerCommittee: targetAggregatorsPerCommittee,
IntervalsPerSlot: intervalsPerSlot,
ForkVersion: genesisResponse.GenesisForkVersion,
GenesisTime: genesisResponse.GenesisTime,
GenesisValidatorsRoot: genesisResponse.GenesisValidatorsRoot,
}

return beaconConfig, nil
Expand Down
9 changes: 6 additions & 3 deletions beacon/goclient/sync_committee_contribution.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
hash := sha256.Sum256(proof)

// Keep the signature if it's an aggregator.
modulo := SyncCommitteeSize / SyncCommitteeSubnetCount / TargetAggregatorsPerSyncSubcommittee
cfg := gc.BeaconConfig()

// as per spec: https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/validator.md#aggregation-selection
modulo := cfg.SyncCommitteeSize / cfg.SyncCommitteeSubnetCount / cfg.TargetAggregatorsPerSyncSubcommittee

Check warning on line 30 in beacon/goclient/sync_committee_contribution.go

View check run for this annotation

Codecov / codecov/patch

beacon/goclient/sync_committee_contribution.go#L27-L30

Added lines #L27 - L30 were not covered by tests
Comment thread
iurii-ssv marked this conversation as resolved.
if modulo == uint64(0) {
// Modulo must be at least 1.
modulo = 1
Expand All @@ -34,7 +37,7 @@

// SyncCommitteeSubnetID returns sync committee subnet ID from subcommittee index
func (gc *GoClient) SyncCommitteeSubnetID(index phase0.CommitteeIndex) uint64 {
return uint64(index) / (SyncCommitteeSize / SyncCommitteeSubnetCount)
return uint64(index) / (gc.BeaconConfig().SyncCommitteeSize / gc.BeaconConfig().SyncCommitteeSubnetCount)

Check warning on line 40 in beacon/goclient/sync_committee_contribution.go

View check run for this annotation

Codecov / codecov/patch

beacon/goclient/sync_committee_contribution.go#L40

Added line #L40 was not covered by tests
}

// GetSyncCommitteeContribution returns
Expand Down Expand Up @@ -154,7 +157,7 @@
// waitForOneThirdSlotDuration waits until one-third of the slot has transpired (SECONDS_PER_SLOT / 3 seconds after slot start time)
func (gc *GoClient) waitForOneThirdSlotDuration(slot phase0.Slot) {
config := gc.getBeaconConfig()
delay := config.SlotDuration / 3 /* a third of the slot duration */
delay := config.IntervalDuration()

Check warning on line 160 in beacon/goclient/sync_committee_contribution.go

View check run for this annotation

Codecov / codecov/patch

beacon/goclient/sync_committee_contribution.go#L160

Added line #L160 was not covered by tests
finalTime := config.GetSlotStartTime(slot).Add(delay)
wait := time.Until(finalTime)
if wait <= 0 {
Expand Down
8 changes: 1 addition & 7 deletions beacon/goclient/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,6 @@ import (
)

var (
SyncCommitteeSize uint64 = 512
SyncCommitteeSubnetCount uint64 = 4
TargetAggregatorsPerSyncSubcommittee uint64 = 16
EpochsPerSyncCommitteePeriod uint64 = 256
TargetAggregatorsPerCommittee uint64 = 16
// FarFutureEpoch is the null representation of an epoch.
FarFutureEpoch phase0.Epoch = math.MaxUint64
IntervalsPerSlot uint64 = 3
FarFutureEpoch phase0.Epoch = math.MaxUint64
Comment thread
iurii-ssv marked this conversation as resolved.
)
1 change: 0 additions & 1 deletion message/validation/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const (
allowedRoundsInFuture = 1
allowedRoundsInPast = 2
LateSlotAllowance = 2
syncCommitteeSize = 512
rsaSignatureSize = 256
operatorIDSize = 8 // uint64
slotSize = 8 // uint64
Expand Down
3 changes: 2 additions & 1 deletion message/validation/partial_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ func (mv *messageValidator) validatePartialSigMessagesByDutyLogic(

if signedSSVMessage.SSVMessage.MsgID.GetRoleType() == spectypes.RoleCommittee {
// Rule: The number of signatures must be <= min(2*V, V + SYNC_COMMITTEE_SIZE) where V is the number of validators assigned to the cluster
if partialSignatureMessageCount > min(2*clusterValidatorCount, clusterValidatorCount+syncCommitteeSize) {
// #nosec G115
if partialSignatureMessageCount > min(2*clusterValidatorCount, clusterValidatorCount+int(mv.netCfg.GetSyncCommitteeSize())) {
return ErrTooManyPartialSignatureMessages
}

Expand Down
4 changes: 1 addition & 3 deletions message/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,6 @@ func (mv *messageValidator) getValidationLock(key peerIDWithMessageID) *sync.Mut

lock := &sync.Mutex{}

epochDuration := time.Duration(mv.netCfg.GetSlotsPerEpoch()) * mv.netCfg.GetSlotDuration() // #nosec G115 - slots per epoch never exceeds math.MaxInt64
// validationLockTTL specifies how much time a particular validation lock is meant to
// live. It must be large enough for validation lock to never expire while we still are
// expecting to process messages targeting that same validation lock. For a message
Expand All @@ -255,8 +254,7 @@ func (mv *messageValidator) getValidationLock(key peerIDWithMessageID) *sync.Mut
// be allowed to take place).
// 2 epoch duration is a safe TTL to use - message validation will reject processing
// for any message older than that.
validationLockTTL := 2 * epochDuration
mv.validationLockCache.Set(key, lock, validationLockTTL)
mv.validationLockCache.Set(key, lock, 2*mv.netCfg.EpochDuration())

return lock, nil
})
Expand Down
1 change: 0 additions & 1 deletion network/topics/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,6 @@ func newPeer(ctx context.Context, logger *zap.Logger, t *testing.T, msgValidator
Scoring: &topics.ScoringConfig{
IPWhitelist: nil,
IPColocationWeight: 0,
OneEpochDuration: time.Minute,
},
MsgValidator: msgValidator,
ScoreInspector: scoreInspector,
Expand Down
4 changes: 0 additions & 4 deletions network/topics/params/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ import (
"github.com/pkg/errors"
)

const (
oneEpochDuration = (12 * time.Second) * 32
)

// scoreDecay determines the decay rate from the provided time period till
// the decayToZero value. Ex: ( 1 -> 0.01)
func scoreDecay(totalDecayDuration time.Duration, decayIntervalDuration time.Duration) float64 {
Expand Down
Loading