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

FLIP 204: Update cruisectl.BlockTimeController to use TargetEndTime, TargetDuration #5023

Merged
Show file tree
Hide file tree
Changes from 125 commits
Commits
Show all changes
130 commits
Select commit Hold shift + click to select a range
bc5e7ef
unit tests, integration tests using buildjet-4vcpu runner
gomisha Oct 30, 2023
fb69048
listTargetPackages() returns map of CI runners
gomisha Nov 1, 2023
291e71d
test for custom runners
gomisha Nov 1, 2023
e7a7f7e
generateTestMatrix() stores CI runner
gomisha Nov 1, 2023
371e4b3
more testing with custom CI runners
gomisha Nov 1, 2023
00117a4
CI test - 2 unit tests running buildjet runners
gomisha Nov 1, 2023
6a25c05
increase engine unit tests to 8 vCPUs
gomisha Nov 1, 2023
0a3854b
resource manager full load test (8 vCPUs)
gomisha Nov 2, 2023
983e488
network/test tests unquarantined, increased runners
gomisha Nov 2, 2023
0b422d5
Merge branch 'master' into misha/6894-buildjet-ci-test
gomisha Nov 2, 2023
6048198
increased to 16 vCPUs
gomisha Nov 2, 2023
eb81e79
increased engine tests to 16 vCPUs
gomisha Nov 3, 2023
d496e7f
insecure module uses buildjet 4 vcpu runner
gomisha Nov 3, 2023
d320b6b
bft framework integration test using buildjet
gomisha Nov 3, 2023
620d6a1
engine tests split up to 6 jobs with default runners
gomisha Nov 3, 2023
daeac5f
added back all integration tests
gomisha Nov 3, 2023
98c5197
upgraded runners for some integration tests, engine/execution
gomisha Nov 3, 2023
1259067
dummy commit to kick off CI
gomisha Nov 3, 2023
959bf17
split up TestScriptExecutionAndGetAccounts into 3 tests
gomisha Nov 3, 2023
027513c
updated runners for Epoch Cohort2, Access Integration Tests
gomisha Nov 6, 2023
e6a5ef3
AN integration tests split up into 3 cohorts (skip unit, other integr…
gomisha Nov 6, 2023
10c9edd
docker build using GitHub cache
gomisha Nov 6, 2023
c589487
remove saving Docker image locally
gomisha Nov 6, 2023
5998a0d
cache v3, saving local tar before caching, 8vcpu
gomisha Nov 6, 2023
9f86a31
add 11 docker images to docker-images.tar, 16 vcpu
gomisha Nov 6, 2023
ba1b00f
docker save multiline fix; skip localnet-test
gomisha Nov 6, 2023
544b877
docker build increase to 32 vcpu
gomisha Nov 6, 2023
99a9b9e
buildjet cache instead of GitHub cache
gomisha Nov 6, 2023
0e4d303
lint fix
gomisha Nov 6, 2023
94192f6
activate more integration tests with default runners, using cached Do…
gomisha Nov 6, 2023
c1f10f1
docker-build downsized to 16 vcpu
gomisha Nov 6, 2023
5ebfaa0
integration test without relic build
gomisha Nov 6, 2023
6ca0231
put back relic build for integration tests
gomisha Nov 6, 2023
8766f2a
put back all remaining integration tests using BuildJet runners
gomisha Nov 6, 2023
d637a60
Merge branch 'master' into misha/6894-buildjet-ci-test
gomisha Nov 6, 2023
deab1b1
Merge branch 'misha/6894-buildjet-ci-test' of https://github.com/onfl…
gomisha Nov 6, 2023
a9b3441
integration tests reverted to ubuntu-latest runners
gomisha Nov 7, 2023
034942d
re-activated unit-test, unit-test-modules jobs
gomisha Nov 7, 2023
3037af2
added (failing) test for sub-sub packages
gomisha Nov 7, 2023
35f4706
sub-sub packages support
gomisha Nov 7, 2023
1520df6
sub-sub package test enhanced
gomisha Nov 7, 2023
357d9c5
updated other tests to support new sub-sub packages
gomisha Nov 7, 2023
1591a60
split up engine/execution unit tests into 3 jobs
gomisha Nov 7, 2023
645fc0b
engine/execution/ingestion upgraded to 4 vcpu
gomisha Nov 7, 2023
37ecc81
engine/execution/ingestion:buildjet-8vcpu
gomisha Nov 8, 2023
f52d044
network/test, network/p2p increased to 8 vcpu; added remaining networ…
gomisha Nov 8, 2023
a4bfe9c
BFT Framework, Epoch Cohort 2 - increased to 4 vcpu
gomisha Nov 8, 2023
abc6048
upgraded runners for Access Cohort 1, Epoch Cohort 1, 2
gomisha Nov 8, 2023
91a5adf
epoch cohort2 upgraded to 16 vcpu
gomisha Nov 8, 2023
d0b29ce
BFT Framework upgrade to 8 vcpu, epoch cohort2 removed flaky test, do…
gomisha Nov 8, 2023
655cf1c
quarantined flaky test - TestEpochJoinAndLeaveVN
gomisha Nov 8, 2023
14e0019
quarantined flaky test - TestSealingAndVerificationPassThrough
gomisha Nov 8, 2023
b98a39d
Merge branch 'master' into misha/6894-buildjet-ci-test
gomisha Nov 8, 2023
e2b0cdc
lint fix
gomisha Nov 8, 2023
457ae50
network/test split up into network/test/cohort1, network/test/cohort2
gomisha Nov 8, 2023
1554902
network/p2p split up into 4 subpackages
gomisha Nov 8, 2023
7944c28
extracted network/alsp into separate job
gomisha Nov 8, 2023
6e03881
extracted module/dkg into separate job
gomisha Nov 8, 2023
52bd044
engine/execution/ingestion dowgraded to stock runner
gomisha Nov 8, 2023
32afbca
added engine parent package as separate job
gomisha Nov 8, 2023
d8df732
added storage parent package as separate job
gomisha Nov 8, 2023
ec2d6c5
added state package as separate job
gomisha Nov 8, 2023
43c862e
removed localnet-test job
gomisha Nov 8, 2023
d7c598d
engine/execution/ingestion upgraded to 2 vcpu
gomisha Nov 8, 2023
56a4a17
network/p2p/p2pnode upgraded to 2 vcpu
gomisha Nov 8, 2023
60c281e
module, engine upgraded to 2 vcpu
gomisha Nov 8, 2023
1423ee2
network/p2p/p2pnode upgraded to 4 vcpu
gomisha Nov 8, 2023
de74efb
network/test/cohort2 upgraded to 4 vcpu
gomisha Nov 8, 2023
4884166
engine upgraded to 4 vcpu
gomisha Nov 8, 2023
4ad3fa4
engine/execution/ingestion upgraded to 4 vcpu, network/test/cohort1 u…
gomisha Nov 8, 2023
acdb459
network/test/cohort1 upgraded to 4 vcpu
gomisha Nov 8, 2023
3ed7c01
engine/execution/ingestion upgraded to 8 vcpu
gomisha Nov 8, 2023
b540d8f
network/test/cohort1 upgraded to 8 vcpu
gomisha Nov 8, 2023
14b8c6c
BFT (Protocol) upgraded to 4 vcpu
gomisha Nov 8, 2023
ab7cd72
network/test/cohort1 upgraded to 16 vcpu
gomisha Nov 8, 2023
aa60cab
BFT (Protocol), Epoch Cohort1 upgraded to 8 vcpu
gomisha Nov 8, 2023
c1826f9
noop push to kick off CI
gomisha Nov 9, 2023
7c96928
Module (integration) upgraded to 4 vcpu
gomisha Nov 9, 2023
ac432e2
TestUnicastRateLimit_Messages flaky test quarantined
gomisha Nov 9, 2023
7c922cb
noop push to kick off CI
gomisha Nov 9, 2023
ced2ce9
buildjet/cache@v3 => actions/cache@v3
gomisha Nov 9, 2023
76e2f53
test retries increased to 5, timeout increased to 35 mins
gomisha Nov 9, 2023
47e71f9
module job increased to 4 vcpu
gomisha Nov 9, 2023
9f889cc
Merge branch 'master' into misha/6894-buildjet-ci-test
gomisha Nov 9, 2023
b60901b
unquarantined epoch flaky test after it was fixed
gomisha Nov 9, 2023
6761410
unlink flaky test monitor workflow from running when ci changes
gomisha Nov 9, 2023
131490c
Merge branch 'misha/6894-buildjet-ci-test' of https://github.com/onfl…
gomisha Nov 9, 2023
8d6dfe4
clean up
gomisha Nov 9, 2023
d9d1b42
lint fix
gomisha Nov 9, 2023
34e52f5
add TargetEndTime to epoch models
jordanschalm Nov 9, 2023
9160e93
update service event parsing
jordanschalm Nov 9, 2023
7f75959
fix some typos and godocs
jordanschalm Nov 9, 2023
3f6157f
update mocks
jordanschalm Nov 10, 2023
8ae7462
lint
jordanschalm Nov 10, 2023
5c0dc57
lint
jordanschalm Nov 10, 2023
72e9efd
Merge pull request #4906 from onflow/misha/6894-buildjet-ci-test
gomisha Nov 10, 2023
a183293
Merge branch 'feature/flip-204-epoch-target-end-time' into jordan/494…
jordanschalm Nov 10, 2023
903ec6c
pin new version of core-contracts
jordanschalm Nov 14, 2023
8c1b340
update expected state commitment
jordanschalm Nov 14, 2023
8d59a9d
update another state commitment constant
jordanschalm Nov 14, 2023
ef207cb
update another state commit constant
jordanschalm Nov 15, 2023
c6f4e7b
use TargetEndTime in cruisectl
jordanschalm Nov 15, 2023
3ab9d18
represent target end time as uint64
jordanschalm Nov 17, 2023
dd6ee78
lint / mocks
jordanschalm Nov 17, 2023
8945871
Merge branch 'jordan/4945-target-end-time' into jordan/4946-cruise-ct…
jordanschalm Nov 17, 2023
8f8620a
use unix time in block time controller
jordanschalm Nov 17, 2023
759ed40
add todod for epoch fallback flag
jordanschalm Nov 17, 2023
faf82cf
Merge branch 'feature/flip-204-epoch-target-end-time' into jordan/494…
jordanschalm Nov 17, 2023
80e671e
wip
jordanschalm Nov 17, 2023
12a5169
wip - begin adding duration
jordanschalm Nov 20, 2023
867579e
Merge branch 'feature/flip-204-epoch-target-end-time' of github.com:o…
jordanschalm Nov 20, 2023
3df3443
add TargetDuration to models, conversion
jordanschalm Nov 20, 2023
813eaa5
bump core-contracts version
jordanschalm Nov 20, 2023
e9e235c
update state commitment constants in tests
jordanschalm Nov 20, 2023
e1a7050
tidy
jordanschalm Nov 20, 2023
7899406
update mocks
jordanschalm Nov 20, 2023
23578b6
Merge branch 'jordan/4945-target-duration' into jordan/4946-cruise-ct…
jordanschalm Nov 20, 2023
fd98175
track target duration in block time ctl
jordanschalm Nov 20, 2023
65742dd
remove transition_time
jordanschalm Nov 20, 2023
5b1fcb6
update tests
jordanschalm Nov 20, 2023
de48577
fix last 2 tests
jordanschalm Nov 20, 2023
b1cf665
Update consensus/hotstuff/cruisectl/block_time_controller.go
jordanschalm Nov 20, 2023
9318c52
Update consensus/hotstuff/cruisectl/block_time_controller_test.go
jordanschalm Nov 20, 2023
703dcb4
Update consensus/hotstuff/cruisectl/block_time_controller_test.go
jordanschalm Nov 20, 2023
5e040cf
lint
jordanschalm Nov 20, 2023
b8f54b7
Merge branch 'feature/flip-204-epoch-target-end-time' into jordan/494…
jordanschalm Nov 23, 2023
267c10f
Apply suggestions from code review
jordanschalm Nov 23, 2023
92f1b29
add docs
jordanschalm Nov 23, 2023
5db96db
add docs for config setter/getters
jordanschalm Nov 23, 2023
4d2d073
gofmt
jordanschalm Nov 23, 2023
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: 0 additions & 10 deletions cmd/consensus/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ func main() {
dkgControllerConfig dkgmodule.ControllerConfig
dkgMessagingEngineConfig = dkgeng.DefaultMessagingEngineConfig()
cruiseCtlConfig = cruisectl.DefaultConfig()
cruiseCtlTargetTransitionTimeFlag = cruiseCtlConfig.TargetTransition.String()
cruiseCtlFallbackProposalDurationFlag time.Duration
cruiseCtlMinViewDurationFlag time.Duration
cruiseCtlMaxViewDurationFlag time.Duration
Expand Down Expand Up @@ -150,7 +149,6 @@ func main() {
flags.DurationVar(&hotstuffMinTimeout, "hotstuff-min-timeout", 2500*time.Millisecond, "the lower timeout bound for the hotstuff pacemaker, this is also used as initial timeout")
flags.Float64Var(&hotstuffTimeoutAdjustmentFactor, "hotstuff-timeout-adjustment-factor", timeout.DefaultConfig.TimeoutAdjustmentFactor, "adjustment of timeout duration in case of time out event")
flags.Uint64Var(&hotstuffHappyPathMaxRoundFailures, "hotstuff-happy-path-max-round-failures", timeout.DefaultConfig.HappyPathMaxRoundFailures, "number of failed rounds before first timeout increase")
flags.StringVar(&cruiseCtlTargetTransitionTimeFlag, "cruise-ctl-target-epoch-transition-time", cruiseCtlTargetTransitionTimeFlag, "the target epoch switchover schedule")
flags.DurationVar(&cruiseCtlFallbackProposalDurationFlag, "cruise-ctl-fallback-proposal-duration", cruiseCtlConfig.FallbackProposalDelay.Load(), "the proposal duration value to use when the controller is disabled, or in epoch fallback mode. In those modes, this value has the same as the old `--block-rate-delay`")
flags.DurationVar(&cruiseCtlMinViewDurationFlag, "cruise-ctl-min-view-duration", cruiseCtlConfig.MinViewDuration.Load(), "the lower bound of authority for the controller, when active. This is the smallest amount of time a view is allowed to take.")
flags.DurationVar(&cruiseCtlMaxViewDurationFlag, "cruise-ctl-max-view-duration", cruiseCtlConfig.MaxViewDuration.Load(), "the upper bound of authority for the controller when active. This is the largest amount of time a view is allowed to take.")
Expand Down Expand Up @@ -179,14 +177,6 @@ func main() {
startupTime = t
nodeBuilder.Logger.Info().Time("startup_time", startupTime).Msg("got startup_time")
}
// parse target transition time string, if set
if cruiseCtlTargetTransitionTimeFlag != cruiseCtlConfig.TargetTransition.String() {
transitionTime, err := cruisectl.ParseTransition(cruiseCtlTargetTransitionTimeFlag)
if err != nil {
return fmt.Errorf("invalid epoch transition time string: %w", err)
}
cruiseCtlConfig.TargetTransition = *transitionTime
}
// convert local flag variables to atomic config variables, for dynamically updatable fields
if cruiseCtlEnabledFlag != cruiseCtlConfig.Enabled.Load() {
cruiseCtlConfig.Enabled.Store(cruiseCtlEnabledFlag)
Expand Down
111 changes: 84 additions & 27 deletions consensus/hotstuff/cruisectl/block_time_controller.go
jordanschalm marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,20 @@ type TimedBlock struct {
// epochInfo stores data about the current and next epoch. It is updated when we enter
// the first view of a new epoch, or the EpochSetup phase of the current epoch.
type epochInfo struct {
curEpochFirstView uint64
curEpochFinalView uint64 // F[v] - the final view of the epoch
curEpochTargetEndTime time.Time // T[v] - the target end time of the current epoch
nextEpochFinalView *uint64
curEpochFirstView uint64
curEpochFinalView uint64 // F[v] - the final view of the current epoch
curEpochTargetDuration uint64
jordanschalm marked this conversation as resolved.
Show resolved Hide resolved
curEpochTargetEndTime uint64 // T[v] - the target end time of the current epoch, represented as Unix Time [seconds]
nextEpochFinalView *uint64 // the final view of the next epoch
nextEpochTargetDuration *uint64
jordanschalm marked this conversation as resolved.
Show resolved Hide resolved
nextEpochTargetEndTime *uint64 // the target end time of the next epoch, represented as Unix Time [seconds]
}

// targetViewTime returns τ[v], the ideal, steady-state view time for the current epoch.
// For numerical stability, we avoid repetitive conversions between seconds and time.Duration.
// Instead, internally within the controller, we work with float64 in units of seconds.
func (epoch *epochInfo) targetViewTime() float64 {
return epochLength.Seconds() / float64(epoch.curEpochFinalView-epoch.curEpochFirstView+1)
}

// fractionComplete returns the percentage of views completed of the epoch for the given curView.
// curView must be within the range [curEpochFirstView, curEpochFinalView]
// Returns the completion percentage as a float between [0, 1]
func (epoch *epochInfo) fractionComplete(curView uint64) float64 {
return float64(curView-epoch.curEpochFirstView) / float64(epoch.curEpochFinalView-epoch.curEpochFirstView)
return float64(epoch.curEpochTargetDuration) / float64(epoch.curEpochFinalView-epoch.curEpochFirstView+1)
}

// BlockTimeController dynamically adjusts the ProposalTiming of this node,
Expand All @@ -67,8 +63,8 @@ func (epoch *epochInfo) fractionComplete(curView uint64) float64 {
// This low-level controller output `(B0, x0, d)` is wrapped into a `ProposalTiming`
// interface, specifically `happyPathBlockTime` on the happy path. The purpose of the
// `ProposalTiming` wrapper is to translate the raw controller output into a form
// that is useful for the event handler. Edge cases, such as initialization or
// EECC are implemented by other implementations of `ProposalTiming`.
// that is useful for the EventHandler. Edge cases, such as initialization or
// epoch fallback are implemented by other implementations of `ProposalTiming`.
type BlockTimeController struct {
component.Component
protocol.Consumer // consumes protocol state events
Expand All @@ -79,7 +75,9 @@ type BlockTimeController struct {
log zerolog.Logger
metrics module.CruiseCtlMetrics

epochInfo // scheduled transition view for current/next epoch
epochInfo // scheduled transition view for current/next epoch
// Currently, the only possible state transition for `epochFallbackTriggered` is false → true.
// TODO for 'leaving Epoch Fallback via special service event' this might need to change.
epochFallbackTriggered bool

incorporatedBlocks chan TimedBlock // OnBlockIncorporated events, we desire these blocks to be processed in a timely manner and therefore use a small channel capacity
Expand Down Expand Up @@ -162,6 +160,18 @@ func (ctl *BlockTimeController) initEpochInfo(curView uint64) error {
}
ctl.curEpochFinalView = curEpochFinalView

curEpochTargetDuration, err := curEpoch.TargetDuration()
if err != nil {
return fmt.Errorf("could not initialize current epoch target duration: %w", err)
}
ctl.curEpochTargetDuration = curEpochTargetDuration

curEpochTargetEndTime, err := curEpoch.TargetEndTime()
if err != nil {
return fmt.Errorf("could not initialize current epoch target end time: %w", err)
}
ctl.curEpochTargetEndTime = curEpochTargetEndTime

phase, err := finalSnapshot.Phase()
if err != nil {
return fmt.Errorf("could not check snapshot phase: %w", err)
Expand All @@ -172,9 +182,19 @@ func (ctl *BlockTimeController) initEpochInfo(curView uint64) error {
return fmt.Errorf("could not initialize next epoch final view: %w", err)
}
ctl.epochInfo.nextEpochFinalView = &nextEpochFinalView
}

ctl.curEpochTargetEndTime = ctl.config.TargetTransition.inferTargetEndTime(time.Now().UTC(), ctl.epochInfo.fractionComplete(curView))
nextEpochTargetDuration, err := finalSnapshot.Epochs().Next().TargetDuration()
if err != nil {
return fmt.Errorf("could not initialize next epoch target duration: %w", err)
}
ctl.nextEpochTargetDuration = &nextEpochTargetDuration

nextEpochTargetEndTime, err := finalSnapshot.Epochs().Next().TargetEndTime()
if err != nil {
return fmt.Errorf("could not initialize next epoch target end time: %w", err)
}
ctl.nextEpochTargetEndTime = &nextEpochTargetEndTime
}

epochFallbackTriggered, err := ctl.state.Params().EpochFallbackTriggered()
if err != nil {
Expand All @@ -197,8 +217,7 @@ func (ctl *BlockTimeController) initProposalTiming(curView uint64) {
ctl.storeProposalTiming(newPublishImmediately(curView, time.Now().UTC()))
}

// storeProposalTiming stores the latest ProposalTiming
// Concurrency safe.
// storeProposalTiming stores the latest ProposalTiming. Concurrency safe.
func (ctl *BlockTimeController) storeProposalTiming(proposalTiming ProposalTiming) {
ctl.latestProposalTiming.Store(&proposalTiming)
}
Expand Down Expand Up @@ -242,7 +261,7 @@ func (ctl *BlockTimeController) processEventsWorkerLogic(ctx irrecoverable.Signa
case <-ctl.epochFallbacks:
err := ctl.processEpochFallbackTriggered()
if err != nil {
ctl.log.Err(err).Msgf("fatal error processing epoch EECC event")
ctl.log.Err(err).Msgf("fatal error processing epoch fallback event")
ctx.Throw(err)
}
default:
Expand Down Expand Up @@ -270,7 +289,7 @@ func (ctl *BlockTimeController) processEventsWorkerLogic(ctx irrecoverable.Signa
case <-ctl.epochFallbacks:
err := ctl.processEpochFallbackTriggered()
if err != nil {
ctl.log.Err(err).Msgf("fatal error processing epoch EECC event")
ctl.log.Err(err).Msgf("fatal error processing epoch fallback event")
ctx.Throw(err)
return
}
Expand Down Expand Up @@ -321,15 +340,24 @@ func (ctl *BlockTimeController) checkForEpochTransition(tb TimedBlock) error {
if ctl.nextEpochFinalView == nil { // final view of epoch we are entering should be known
return fmt.Errorf("cannot transition without nextEpochFinalView set")
}
if ctl.nextEpochTargetEndTime == nil {
return fmt.Errorf("cannot transition without nextEpochTargetEndTime set")
}
if ctl.nextEpochTargetDuration == nil {
return fmt.Errorf("cannot transition without nextEpochTargetDuration set")
}
if view > *ctl.nextEpochFinalView { // the block's view should be within the upcoming epoch
return fmt.Errorf("sanity check failed: curView %d is beyond both current epoch (final view %d) and next epoch (final view %d)",
view, ctl.curEpochFinalView, *ctl.nextEpochFinalView)
}

ctl.curEpochFirstView = ctl.curEpochFinalView + 1
ctl.curEpochFinalView = *ctl.nextEpochFinalView
ctl.curEpochTargetDuration = *ctl.nextEpochTargetDuration
ctl.curEpochTargetEndTime = *ctl.nextEpochTargetEndTime
ctl.nextEpochFinalView = nil
ctl.curEpochTargetEndTime = ctl.config.TargetTransition.inferTargetEndTime(tb.Block.Timestamp, ctl.epochInfo.fractionComplete(view))
ctl.nextEpochTargetDuration = nil
ctl.nextEpochTargetEndTime = nil
return nil
}

Expand Down Expand Up @@ -364,7 +392,8 @@ func (ctl *BlockTimeController) measureViewDuration(tb TimedBlock) error {
// constructs the child (for first view of new epoch). The last view of the epoch ends, when the child proposal is published.
tau := ctl.targetViewTime() // τ - idealized target view time in units of seconds
viewDurationsRemaining := ctl.curEpochFinalView + 1 - view // k[v] - views remaining in current epoch
jordanschalm marked this conversation as resolved.
Show resolved Hide resolved
durationRemaining := ctl.curEpochTargetEndTime.Sub(tb.TimeObserved)

durationRemaining := u2t(ctl.curEpochTargetEndTime).Sub(tb.TimeObserved)
jordanschalm marked this conversation as resolved.
Show resolved Hide resolved

// Compute instantaneous error term: e[v] = k[v]·τ - T[v] i.e. the projected difference from target switchover
// and update PID controller's error terms. All UNITS in SECOND.
Expand All @@ -377,7 +406,8 @@ func (ctl *BlockTimeController) measureViewDuration(tb TimedBlock) error {
u := propErr*ctl.config.KP + itgErr*ctl.config.KI + drivErr*ctl.config.KD

// compute the controller output for this observation
unconstrainedBlockTime := time.Duration((tau - u) * float64(time.Second)) // desired time between parent and child block, in units of seconds

jordanschalm marked this conversation as resolved.
Show resolved Hide resolved
unconstrainedBlockTime := f2d(tau - u) // desired time between parent and child block, in units of seconds
proposalTiming := newHappyPathBlockTime(tb, unconstrainedBlockTime, ctl.config.TimingConfig)
constrainedBlockTime := proposalTiming.ConstrainedBlockTime()

Expand All @@ -390,13 +420,13 @@ func (ctl *BlockTimeController) measureViewDuration(tb TimedBlock) error {
Float64("proportional_err", propErr).
Float64("integral_err", itgErr).
Float64("derivative_err", drivErr).
Dur("controller_output", time.Duration(u*float64(time.Second))).
Dur("controller_output", f2d(u)).
Dur("unconstrained_block_time", unconstrainedBlockTime).
Dur("constrained_block_time", constrainedBlockTime).
Msg("measured error upon view change")

ctl.metrics.PIDError(propErr, itgErr, drivErr)
ctl.metrics.ControllerOutput(time.Duration(u * float64(time.Second)))
ctl.metrics.ControllerOutput(f2d(u))
ctl.metrics.TargetProposalDuration(proposalTiming.ConstrainedBlockTime())

ctl.storeProposalTiming(proposalTiming)
Expand All @@ -416,9 +446,20 @@ func (ctl *BlockTimeController) processEpochSetupPhaseStarted(snapshot protocol.
nextEpoch := snapshot.Epochs().Next()
finalView, err := nextEpoch.FinalView()
if err != nil {
return fmt.Errorf("could not get next epochInfo final view: %w", err)
return fmt.Errorf("could not get next epoch final view: %w", err)
}
targetDuration, err := nextEpoch.TargetDuration()
if err != nil {
return fmt.Errorf("could not get next epoch target duration: %w", err)
}
targetEndTime, err := nextEpoch.TargetEndTime()
if err != nil {
return fmt.Errorf("could not get next epoch target end time: %w", err)
}

ctl.epochInfo.nextEpochFinalView = &finalView
ctl.epochInfo.nextEpochTargetDuration = &targetDuration
ctl.epochInfo.nextEpochTargetEndTime = &targetEndTime
return nil
}

Expand Down Expand Up @@ -460,3 +501,19 @@ func (ctl *BlockTimeController) EpochSetupPhaseStarted(_ uint64, first *flow.Hea
func (ctl *BlockTimeController) EpochEmergencyFallbackTriggered() {
ctl.epochFallbacks <- struct{}{}
}

// t2u converts a time.Time to UNIX time represented as a uint64.
// Returned timestamp is precise to within one second of input.
func t2u(t time.Time) uint64 {
return uint64(t.Unix())
}

// u2t converts a UNIX timestamp represented as a uint64 to a time.Time.
func u2t(unix uint64) time.Time {
return time.Unix(int64(unix), 0)
}

// f2d converts a floating-point number of seconds to a time.Duration.
func f2d(sec float64) time.Duration {
return time.Duration(int64(sec * float64(time.Second)))
}
Loading
Loading