Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core/consensus: add new consensus round timer #3440

Merged
merged 32 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
eb9c935
add new timer and corresponding feature
DiogoSantoss Jan 7, 2025
5052b77
formatting
DiogoSantoss Jan 7, 2025
834c826
add timer test and fix first round to be one instead of zero
DiogoSantoss Jan 7, 2025
9d0bfd0
fix typo in round timer test
DiogoSantoss Jan 7, 2025
19b8a46
add exponential timer to GetTimerFunc()
DiogoSantoss Jan 7, 2025
d7065be
add consensus round timer documentation
DiogoSantoss Jan 7, 2025
b206e2f
add precedence warning to exponential round timer feature
DiogoSantoss Jan 7, 2025
c8a03d3
add exponential to GetTimerFunc test and fix name consistency
DiogoSantoss Jan 7, 2025
f5ca318
fix lint issue
DiogoSantoss Jan 7, 2025
a4eba85
add same timer warning, cli flag, default timer and more exponential …
DiogoSantoss Jan 8, 2025
0ee9b60
fix default timer doc
DiogoSantoss Jan 8, 2025
1afc273
Update docs/consensus.md
DiogoSantoss Jan 14, 2025
f7da772
Update docs/consensus.md
DiogoSantoss Jan 14, 2025
caec6c3
app/eth2wrap: fallback beacon nodes (#3342)
gsora Jan 7, 2025
e4997eb
*: bump protobuf to 1.36.2 (#3439)
KaloyanTanev Jan 7, 2025
1fdc58f
build(deps): Bump go.opentelemetry.io/otel/trace from 1.32.0 to 1.33.…
dependabot[bot] Jan 7, 2025
bc3c6e7
build(deps): Bump go.opentelemetry.io/contrib/instrumentation/net/htt…
dependabot[bot] Jan 8, 2025
8ce78aa
build(deps): Bump google.golang.org/protobuf from 1.35.2 to 1.36.2 (#…
dependabot[bot] Jan 8, 2025
80d5bf9
build(deps): Bump go.opentelemetry.io/otel/exporters/stdout/stdouttra…
dependabot[bot] Jan 8, 2025
d33769e
build(deps): Bump golang.org/x/tools from 0.28.0 to 0.29.0 (#3443)
dependabot[bot] Jan 8, 2025
66f9e65
app/peerinfo: add nickname field to peerinfo protocol (#3428)
DiogoSantoss Jan 8, 2025
586c265
core/validatorapi: v1/v2 endpoints warning (#3431)
pinebit Jan 8, 2025
1bfee74
app: eth2wrap latency logging (#3417)
KaloyanTanev Jan 8, 2025
bd8efb3
*: bump linter to 1.63.4 (#3444)
KaloyanTanev Jan 8, 2025
7752c0b
build: allow golangci-lint parallel on .pre-commit (#3455)
KaloyanTanev Jan 13, 2025
7109f7e
fix: chown -R runner:docker 001 folder (#3441)
apham0001 Jan 13, 2025
b6841e1
docs: contributing discord channel (#3452)
KaloyanTanev Jan 14, 2025
cf785b5
build(deps): Bump github.com/showwin/speedtest-go from 1.7.9 to 1.7.1…
dependabot[bot] Jan 14, 2025
b8d208d
build(deps): Bump golang.org/x/time from 0.8.0 to 0.9.0 (#3446)
dependabot[bot] Jan 14, 2025
a1985c0
build(deps): Bump sigp/lighthouse from v6.0.0 to v6.0.1 in /testutil/…
dependabot[bot] Jan 14, 2025
9e47a84
build(deps): Bump chainsafe/lodestar from v1.23.1 to v1.24.0 in /test…
dependabot[bot] Jan 14, 2025
7dc6b41
build(deps): Bump github.com/attestantio/go-builder-client from 0.5.2…
dependabot[bot] Jan 14, 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
4 changes: 4 additions & 0 deletions app/featureset/featureset.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ const (
// The feature gets automatically enabled when the current network is gnosis|chiado,
// unless the user disabled this feature explicitly.
GnosisBlockHotfix Feature = "gnosis_block_hotfix"

// Exponential enables Exponential round timer for consensus rounds.
DiogoSantoss marked this conversation as resolved.
Show resolved Hide resolved
Exponential Feature = "exponential"
)

var (
Expand All @@ -56,6 +59,7 @@ var (
AggSigDBV2: statusAlpha,
JSONRequests: statusAlpha,
GnosisBlockHotfix: statusAlpha,
Exponential: statusAlpha,
// Add all features and there status here.
}

Expand Down
1 change: 1 addition & 0 deletions app/featureset/featureset_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ func TestAllFeatureStatus(t *testing.T) {
ConsensusParticipate,
JSONRequests,
GnosisBlockHotfix,
Exponential,
}

for _, feature := range features {
Expand Down
46 changes: 46 additions & 0 deletions core/consensus/utils/roundtimer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package utils

import (
"math"
"strings"
"sync"
"time"
Expand All @@ -23,7 +24,14 @@
type TimerFunc func(core.Duty) RoundTimer

// GetTimerFunc returns a timer function based on the enabled features.
func GetTimerFunc() TimerFunc {

Check failure on line 27 in core/consensus/utils/roundtimer.go

View workflow job for this annotation

GitHub Actions / golangci

empty-lines: extra empty line at the start of a block (revive)

if featureset.Enabled(featureset.Exponential) {
return func(core.Duty) RoundTimer {
return NewExponentialRoundTimer()
}

Check warning on line 32 in core/consensus/utils/roundtimer.go

View check run for this annotation

Codecov / codecov/patch

core/consensus/utils/roundtimer.go#L30-L32

Added lines #L30 - L32 were not covered by tests
}

if featureset.Enabled(featureset.EagerDoubleLinear) {
return func(core.Duty) RoundTimer {
return NewDoubleEagerLinearRoundTimer()
Expand All @@ -47,6 +55,7 @@
const (
TimerIncreasing TimerType = "inc"
TimerEagerDoubleLinear TimerType = "eager_dlinear"
Exponential TimerType = "exponential"
)

// increasingRoundTimeout returns the duration for a round that starts at incRoundStart in round 1
Expand Down Expand Up @@ -150,3 +159,40 @@

return timer.Chan(), func() { timer.Stop() }
}

// exponentialRoundTimer implements a round timerType with the following properties:
//
// The first round has one second to complete consensus
// If this round fails then other peers already had time to fetch proposal and therefore
// won't need as much time to reach a consensus. Therefore start timeout with lower value
// which will increase exponentially
type exponentialRoundTimer struct {
clock clockwork.Clock
}

func (*exponentialRoundTimer) Type() TimerType {
return Exponential

Check warning on line 174 in core/consensus/utils/roundtimer.go

View check run for this annotation

Codecov / codecov/patch

core/consensus/utils/roundtimer.go#L173-L174

Added lines #L173 - L174 were not covered by tests
}

func (t *exponentialRoundTimer) Timer(round int64) (<-chan time.Time, func()) {
var timer clockwork.Timer
if round == 1 {
// First round has 1 second
timer = t.clock.NewTimer(time.Second)
} else {
// Subsequent rounds have exponentially more time starting at 200 milliseconds
timer = t.clock.NewTimer(time.Millisecond * time.Duration(math.Pow(2, float64(round-1))*100))
}
return timer.Chan(), func() { timer.Stop() }

Check failure on line 186 in core/consensus/utils/roundtimer.go

View workflow job for this annotation

GitHub Actions / golangci

return with no blank line before (nlreturn)
}

// NewExponentialRoundTimer returns a new exponential round timer type.
func NewExponentialRoundTimer() RoundTimer {
return NewExponentialRoundTimerWithClock(clockwork.NewRealClock())

Check warning on line 191 in core/consensus/utils/roundtimer.go

View check run for this annotation

Codecov / codecov/patch

core/consensus/utils/roundtimer.go#L190-L191

Added lines #L190 - L191 were not covered by tests
}

func NewExponentialRoundTimerWithClock(clock clockwork.Clock) RoundTimer {
return &exponentialRoundTimer{
clock: clock,
}
}
52 changes: 52 additions & 0 deletions core/consensus/utils/roundtimer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,58 @@ func TestDoubleEagerLinearRoundTimer(t *testing.T) {
stop()
}

func TestExponentialRoundTimer(t *testing.T) {
tests := []struct {
name string
round int64
want time.Duration
}{
{
name: "round 1",
round: 1,
want: 1000 * time.Millisecond,
},
{
name: "round 2",
round: 2,
want: 200 * time.Millisecond,
},
{
name: "round 3",
round: 3,
want: 400 * time.Millisecond,
},
{
name: "round 4",
round: 4,
want: 800 * time.Millisecond,
},
}

for _, tt := range tests {
fakeClock := clockwork.NewFakeClock()
timer := utils.NewExponentialRoundTimerWithClock(fakeClock)

t.Run(tt.name, func(t *testing.T) {
// Start the timerType
timerC, stop := timer.Timer(tt.round)

// Advance the fake clock
fakeClock.Advance(tt.want)

// Check if the timerType fires
select {
case <-timerC:
default:
require.Fail(t, "Fail", "Timer(round %d) did not fire, want %v", tt.round, tt.want)
}

// Stop the timerType
stop()
})
}
}

func TestGetTimerFunc(t *testing.T) {
timerFunc := utils.GetTimerFunc()
require.Equal(t, utils.TimerEagerDoubleLinear, timerFunc(core.NewAttesterDuty(0)).Type())
Expand Down
Loading