Skip to content

Commit eeea6cd

Browse files
committed
Merge branch 'stage' into qbft-instance-log-stage-durations
2 parents 5bb0a45 + b24f7dc commit eeea6cd

File tree

10 files changed

+69
-40
lines changed

10 files changed

+69
-40
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ require (
4141
github.com/sourcegraph/conc v0.3.0
4242
github.com/spf13/cobra v1.8.1
4343
github.com/ssvlabs/eth2-key-manager v1.5.6
44-
github.com/ssvlabs/ssv-spec v1.2.0
44+
github.com/ssvlabs/ssv-spec v1.2.2
4545
github.com/ssvlabs/ssv/ssvsigner v0.0.0-20251027161822-0b67ab2cd4f3
4646
github.com/status-im/keycard-go v0.2.0
4747
github.com/stretchr/testify v1.10.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,8 @@ github.com/ssvlabs/go-eth2-client v0.6.31-0.20250922150906-26179dd60c9c h1:iNQoR
772772
github.com/ssvlabs/go-eth2-client v0.6.31-0.20250922150906-26179dd60c9c/go.mod h1:fvULSL9WtNskkOB4i+Yyr6BKpNHXvmpGZj9969fCrfY=
773773
github.com/ssvlabs/ssv-spec v1.2.0 h1:RCrFTn3T+IN1oio+m0TnaosyrBXlBgFvAJ91GPnJK78=
774774
github.com/ssvlabs/ssv-spec v1.2.0/go.mod h1:GedhFYGHVJRYYH3nEp05Gn14tyvg6VbTbaIxrMtI7Cg=
775+
github.com/ssvlabs/ssv-spec v1.2.2 h1:as84CsvYAL4+czKBVeQSlxjDYVmU1wClwhc7YNcoBzY=
776+
github.com/ssvlabs/ssv-spec v1.2.2/go.mod h1:GedhFYGHVJRYYH3nEp05Gn14tyvg6VbTbaIxrMtI7Cg=
775777
github.com/ssvlabs/ssv/ssvsigner v0.0.0-20251027161822-0b67ab2cd4f3 h1:eIn/PpHupEa+8lp3E1Q1kNx0IK6udBqCNVEWaC9JlnM=
776778
github.com/ssvlabs/ssv/ssvsigner v0.0.0-20251027161822-0b67ab2cd4f3/go.mod h1:VSxiqWR75EXq29KpoAnp+M9w0MrE6AirTgoQ5LBiAwg=
777779
github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA=

operator/validator/controller.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,10 @@ type ControllerOptions struct {
8989
ProposerDelay time.Duration
9090

9191
// worker flags
92-
WorkersCount int `yaml:"MsgWorkersCount" env:"MSG_WORKERS_COUNT" env-default:"256" env-description:"Number of message processing workers"`
93-
QueueBufferSize int `yaml:"MsgWorkerBufferSize" env:"MSG_WORKER_BUFFER_SIZE" env-default:"65536" env-description:"Size of message worker queue buffer"`
94-
GasLimit uint64 `yaml:"ExperimentalGasLimit" env:"EXPERIMENTAL_GAS_LIMIT" env-description:"Gas limit for MEV block proposals (must match across committee, otherwise MEV fails). Do not change unless you know what you're doing"`
92+
WorkersCount int `yaml:"MsgWorkersCount" env:"MSG_WORKERS_COUNT" env-default:"256" env-description:"Number of message processing workers"`
93+
QueueBufferSize int `yaml:"MsgWorkerBufferSize" env:"MSG_WORKER_BUFFER_SIZE" env-default:"65536" env-description:"Size of message worker queue buffer"`
94+
GasLimit uint64 `yaml:"ExperimentalGasLimit" env:"EXPERIMENTAL_GAS_LIMIT" env-description:"Gas limit for MEV block proposals (must match across committee, otherwise MEV fails). Do not change unless you know what you're doing"`
95+
MajorityForkProtectionStrict bool `yaml:"MajorityForkProtectionStrict" env:"MAJORITY_FORK_PROTECTION_STRICT" env-description:"Refuse to sign attestations with different target roots than your own. This does not increase validator safety. Instead, this is potentially more beneficial for Ethereum (area of active research), at the cost of potentially decrease validator performance during transitory disagreements between operators (e.g., when some of the operators' Beacon nodes are behind, and during re-orgs)."`
9596
}
9697

9798
type Nonce uint16
@@ -170,7 +171,8 @@ type Controller struct {
170171

171172
// NewController creates a new validator controller instance.
172173
func NewController(logger *zap.Logger, options ControllerOptions, exporterOptions exporter.Options) *Controller {
173-
logger.Debug("setting up validator controller")
174+
logger.Debug("setting up validator controller",
175+
zap.Bool("mfp_strict", options.MajorityForkProtectionStrict))
174176

175177
// lookup in a map that holds all relevant operators
176178
operatorsIDs := &sync.Map{}
@@ -197,6 +199,7 @@ func NewController(logger *zap.Logger, options ControllerOptions, exporterOption
197199
options.MessageValidator,
198200
options.Graffiti,
199201
options.ProposerDelay,
202+
options.MajorityForkProtectionStrict,
200203
)
201204

202205
cacheTTL := 2 * options.NetworkConfig.EpochDuration() // #nosec G115
@@ -1050,6 +1053,7 @@ func SetupCommitteeRunners(
10501053
options.OperatorSigner,
10511054
dutyGuard,
10521055
options.DoppelgangerHandler,
1056+
options.MajorityForkProtectionStrict,
10531057
)
10541058
if err != nil {
10551059
return nil, err

protocol/v2/ssv/runner/committee.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type CommitteeRunner struct {
5454
DutyGuard CommitteeDutyGuard
5555
doppelgangerHandler DoppelgangerProvider
5656
measurements *dutyMeasurements
57+
mfpStrict bool
5758

5859
// ValCheck is used to validate the qbft-value(s) proposed by other Operators.
5960
ValCheck ssv.ValueChecker
@@ -72,6 +73,7 @@ func NewCommitteeRunner(
7273
operatorSigner ssvtypes.OperatorSigner,
7374
dutyGuard CommitteeDutyGuard,
7475
doppelgangerHandler DoppelgangerProvider,
76+
mfpStrict bool,
7577
) (Runner, error) {
7678
if len(share) == 0 {
7779
return nil, errors.New("no shares")
@@ -94,6 +96,7 @@ func NewCommitteeRunner(
9496
DutyGuard: dutyGuard,
9597
doppelgangerHandler: doppelgangerHandler,
9698
measurements: newMeasurementsStore(),
99+
mfpStrict: mfpStrict,
97100
}, nil
98101
}
99102

@@ -1062,6 +1065,7 @@ func (r *CommitteeRunner) executeDuty(ctx context.Context, logger *zap.Logger, d
10621065
r.attestingValidators,
10631066
r.GetNetworkConfig().EstimatedCurrentEpoch(),
10641067
vote,
1068+
r.mfpStrict,
10651069
)
10661070
if err := r.BaseRunner.decide(ctx, logger, duty.DutySlot(), vote, r.ValCheck); err != nil {
10671071
return fmt.Errorf("qbft-decide: %w", err)

protocol/v2/ssv/spectest/msg_processing_type.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ var baseCommitteeWithRunnerSample = func(
280280
runnerSample.GetOperatorSigner(),
281281
committeeDutyGuard,
282282
runnerSample.GetDoppelgangerHandler(),
283+
false,
283284
)
284285
return r.(*runner.CommitteeRunner), err
285286
}

protocol/v2/ssv/testing/runner.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ var ConstructBaseRunner = func(
8989
switch role {
9090
case spectypes.RoleCommittee:
9191
valCheck = ssv.NewVoteChecker(km, spectestingutils.TestingDutySlot,
92-
[]phase0.BLSPubKey{phase0.BLSPubKey(share.SharePubKey)}, spectestingutils.TestingDutyEpoch, vote)
92+
[]phase0.BLSPubKey{phase0.BLSPubKey(share.SharePubKey)}, spectestingutils.TestingDutyEpoch, vote, false)
9393
case spectypes.RoleProposer:
9494
valCheck = ssv.NewProposerChecker(km, networkconfig.TestNetwork.Beacon,
9595
(spectypes.ValidatorPK)(spectestingutils.TestingValidatorPubKey), spectestingutils.TestingValidatorIndex,
@@ -138,6 +138,7 @@ var ConstructBaseRunner = func(
138138
opSigner,
139139
dutyGuard,
140140
dgHandler,
141+
false,
141142
)
142143
case spectypes.RoleAggregator:
143144
rnr, err := runner.NewAggregatorRunner(
@@ -221,6 +222,7 @@ var ConstructBaseRunner = func(
221222
opSigner,
222223
dutyGuard,
223224
dgHandler,
225+
false,
224226
)
225227
r.(*runner.CommitteeRunner).BaseRunner.RunnerRoleType = spectestingutils.UnknownDutyType
226228
default:
@@ -356,7 +358,7 @@ var ConstructBaseRunnerWithShareMap = func(
356358
switch role {
357359
case spectypes.RoleCommittee:
358360
valCheck = ssv.NewVoteChecker(km, spectestingutils.TestingDutySlot,
359-
sharePubKeys, spectestingutils.TestingDutyEpoch, vote)
361+
sharePubKeys, spectestingutils.TestingDutyEpoch, vote, false)
360362
case spectypes.RoleProposer:
361363
valCheck = ssv.NewProposerChecker(km, networkconfig.TestNetwork.Beacon,
362364
shareInstance.ValidatorPubKey, shareInstance.ValidatorIndex, phase0.BLSPubKey(shareInstance.SharePubKey))
@@ -400,6 +402,7 @@ var ConstructBaseRunnerWithShareMap = func(
400402
opSigner,
401403
dutyGuard,
402404
dgHandler,
405+
false,
403406
)
404407
case spectypes.RoleAggregator:
405408
rnr, err := runner.NewAggregatorRunner(
@@ -483,6 +486,7 @@ var ConstructBaseRunnerWithShareMap = func(
483486
opSigner,
484487
dutyGuard,
485488
dgHandler,
489+
false,
486490
)
487491
if r != nil {
488492
r.(*runner.CommitteeRunner).BaseRunner.RunnerRoleType = spectestingutils.UnknownDutyType

protocol/v2/ssv/validator/opts.go

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,22 @@ type Options struct {
2929

3030
// CommonOptions represents options that all validators share.
3131
type CommonOptions struct {
32-
NetworkConfig *networkconfig.Network
33-
Network specqbft.Network
34-
Beacon beacon.BeaconNode
35-
Storage *storage.ParticipantStores
36-
Signer ekm.BeaconSigner
37-
OperatorSigner ssvtypes.OperatorSigner
38-
DoppelgangerHandler runner.DoppelgangerProvider
39-
NewDecidedHandler qbftctrl.NewDecidedHandler
40-
FullNode bool
41-
ExporterOptions exporter.Options
42-
QueueSize int
43-
GasLimit uint64
44-
MessageValidator validation.MessageValidator
45-
Graffiti []byte
46-
ProposerDelay time.Duration
32+
NetworkConfig *networkconfig.Network
33+
Network specqbft.Network
34+
Beacon beacon.BeaconNode
35+
Storage *storage.ParticipantStores
36+
Signer ekm.BeaconSigner
37+
OperatorSigner ssvtypes.OperatorSigner
38+
DoppelgangerHandler runner.DoppelgangerProvider
39+
NewDecidedHandler qbftctrl.NewDecidedHandler
40+
FullNode bool
41+
ExporterOptions exporter.Options
42+
QueueSize int
43+
GasLimit uint64
44+
MessageValidator validation.MessageValidator
45+
Graffiti []byte
46+
ProposerDelay time.Duration
47+
MajorityForkProtectionStrict bool
4748
}
4849

4950
func NewCommonOptions(
@@ -62,23 +63,25 @@ func NewCommonOptions(
6263
messageValidator validation.MessageValidator,
6364
graffiti []byte,
6465
proposerDelay time.Duration,
66+
mfpStrict bool,
6567
) *CommonOptions {
6668
result := &CommonOptions{
67-
NetworkConfig: networkConfig,
68-
Network: network,
69-
Beacon: beacon,
70-
Storage: storage,
71-
Signer: signer,
72-
OperatorSigner: operatorSigner,
73-
DoppelgangerHandler: doppelgangerHandler,
74-
NewDecidedHandler: newDecidedHandler,
75-
FullNode: fullNode,
76-
ExporterOptions: exporterOptions,
77-
QueueSize: 1000,
78-
GasLimit: gasLimit,
79-
MessageValidator: messageValidator,
80-
Graffiti: graffiti,
81-
ProposerDelay: proposerDelay,
69+
NetworkConfig: networkConfig,
70+
Network: network,
71+
Beacon: beacon,
72+
Storage: storage,
73+
Signer: signer,
74+
OperatorSigner: operatorSigner,
75+
DoppelgangerHandler: doppelgangerHandler,
76+
NewDecidedHandler: newDecidedHandler,
77+
FullNode: fullNode,
78+
ExporterOptions: exporterOptions,
79+
QueueSize: 1000,
80+
GasLimit: gasLimit,
81+
MessageValidator: messageValidator,
82+
Graffiti: graffiti,
83+
ProposerDelay: proposerDelay,
84+
MajorityForkProtectionStrict: mfpStrict,
8285
}
8386

8487
// If full node, increase the queue size to make enough room for history sync batches to be pushed whole.

protocol/v2/ssv/value_check.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ type voteChecker struct {
2323
sharePublicKeys []phase0.BLSPubKey
2424
estimatedCurrentEpoch phase0.Epoch
2525
expectedVote *spectypes.BeaconVote
26+
mfpStrict bool
2627
}
2728

2829
func NewVoteChecker(
@@ -31,13 +32,15 @@ func NewVoteChecker(
3132
sharePublicKeys []phase0.BLSPubKey,
3233
estimatedCurrentEpoch phase0.Epoch,
3334
expectedVote *spectypes.BeaconVote,
35+
mfpStrict bool,
3436
) ValueChecker {
3537
return &voteChecker{
3638
signer: signer,
3739
slot: slot,
3840
sharePublicKeys: sharePublicKeys,
3941
estimatedCurrentEpoch: estimatedCurrentEpoch,
4042
expectedVote: expectedVote,
43+
mfpStrict: mfpStrict,
4144
}
4245
}
4346

@@ -68,8 +71,8 @@ func (v *voteChecker) CheckValue(value []byte) error {
6871
}
6972
}
7073

71-
// Implemented according to https://github.com/ssvlabs/SIPs/pull/69, except the target root check is deleted
72-
// because reorgs/orphaned blocks will trigger the protection and cause performance drops.
74+
// Implemented according to https://github.com/ssvlabs/SIPs/pull/69, except the target root check is optional,
75+
// because reorgs/orphaned blocks will trigger the target root mismatch and cause attestation misses.
7376
if bv.Source.Epoch != v.expectedVote.Source.Epoch {
7477
return fmt.Errorf("unexpected source epoch %v, expected %v", bv.Source.Epoch, v.expectedVote.Source.Epoch)
7578
}
@@ -82,6 +85,12 @@ func (v *voteChecker) CheckValue(value []byte) error {
8285
return fmt.Errorf("unexpected source root %x, expected %x", bv.Source.Root, v.expectedVote.Source.Root)
8386
}
8487

88+
if v.mfpStrict {
89+
if bv.Target.Root != v.expectedVote.Target.Root {
90+
return fmt.Errorf("unexpected target root %x, expected %x", bv.Target.Root, v.expectedVote.Target.Root)
91+
}
92+
}
93+
8594
return nil
8695
}
8796

ssvsigner/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ require (
3131
github.com/sourcegraph/conc v0.3.0
3232
github.com/ssvlabs/eth2-key-manager v1.5.6
3333
github.com/ssvlabs/ssv v1.2.1-0.20250904093034-64dc248758c3
34-
github.com/ssvlabs/ssv-spec v1.2.0
34+
github.com/ssvlabs/ssv-spec v1.2.2
3535
github.com/stretchr/testify v1.10.0
3636
github.com/testcontainers/testcontainers-go v0.37.0
3737
github.com/valyala/fasthttp v1.58.0

ssvsigner/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,8 @@ github.com/ssvlabs/eth2-key-manager v1.5.6 h1:BMxVCsbcIlUiiO0hpePkHxzX0yhKgMkEzV
333333
github.com/ssvlabs/eth2-key-manager v1.5.6/go.mod h1:tjzhmMzrc0Lzc/OMW1h9Mz8AhmKH7FQC/nFiMNJ0bd8=
334334
github.com/ssvlabs/ssv-spec v1.2.0 h1:RCrFTn3T+IN1oio+m0TnaosyrBXlBgFvAJ91GPnJK78=
335335
github.com/ssvlabs/ssv-spec v1.2.0/go.mod h1:GedhFYGHVJRYYH3nEp05Gn14tyvg6VbTbaIxrMtI7Cg=
336+
github.com/ssvlabs/ssv-spec v1.2.2 h1:as84CsvYAL4+czKBVeQSlxjDYVmU1wClwhc7YNcoBzY=
337+
github.com/ssvlabs/ssv-spec v1.2.2/go.mod h1:GedhFYGHVJRYYH3nEp05Gn14tyvg6VbTbaIxrMtI7Cg=
336338
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
337339
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
338340
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=

0 commit comments

Comments
 (0)