Skip to content

Commit

Permalink
Merge branch 'master' into flow-evm-events-ccf-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
m-Peter authored Feb 15, 2024
2 parents d6f15ee + ae8ab05 commit 533571f
Show file tree
Hide file tree
Showing 92 changed files with 2,759 additions and 1,572 deletions.
2 changes: 0 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,6 @@ generate-fvm-env-wrappers:
generate-mocks: install-mock-generators
mockery --name '(Connector|PingInfoProvider)' --dir=network/p2p --case=underscore --output="./network/mocknetwork" --outpkg="mocknetwork"
CGO_CFLAGS=$(CRYPTO_FLAG) mockgen -destination=storage/mocks/storage.go -package=mocks github.com/onflow/flow-go/storage Blocks,Headers,Payloads,Collections,Commits,Events,ServiceEvents,TransactionResults
# MERGE: Line below commented out on HEAD, uncommented on master
#CGO_CFLAGS=$(CRYPTO_FLAG) mockgen -destination=module/mocks/network.go -package=mocks github.com/onflow/flow-go/module Local,Requester
CGO_CFLAGS=$(CRYPTO_FLAG) mockgen -destination=network/mocknetwork/mock_network.go -package=mocknetwork github.com/onflow/flow-go/network EngineRegistry
mockery --name='.*' --dir=integration/benchmark/mocksiface --case=underscore --output="integration/benchmark/mock" --outpkg="mock"
mockery --name=ExecutionDataStore --dir=module/executiondatasync/execution_data --case=underscore --output="./module/executiondatasync/execution_data/mock" --outpkg="mock"
Expand Down
1 change: 1 addition & 0 deletions cmd/bootstrap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ go run . rootblock \
--epoch-dkg-phase-length 2000 \
--collection-clusters 1 \
--protocol-version=0 \
--use-default-epoch-timing \
--epoch-commit-safety-threshold=1000 \
--config ./bootstrap-example/node-config.json \
-o ./bootstrap-example \
Expand Down
2 changes: 2 additions & 0 deletions cmd/bootstrap/cmd/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ func constructRootEpochEvents(
Participants: participants.Sort(flow.Canonical[flow.Identity]).ToSkeleton(),
Assignments: assignments,
RandomSource: GenerateRandomSeed(flow.EpochSetupRandomSourceLength),
TargetDuration: flagEpochTimingDuration,
TargetEndTime: rootEpochTargetEndTime(),
}

qcsWithSignerIDs := make([]*flow.QuorumCertificateWithSignerIDs, 0, len(clusterQCs))
Expand Down
51 changes: 47 additions & 4 deletions cmd/bootstrap/cmd/finalize.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"path/filepath"
"strings"
"time"

"github.com/onflow/cadence"

Expand Down Expand Up @@ -121,7 +122,7 @@ func finalize(cmd *cobra.Command, args []string) {
internalNodes := readInternalNodeInfos()
log.Info().Msg("")

log.Info().Msg("checking constraints on consensus/cluster nodes")
log.Info().Msg("checking constraints on consensus nodes")
checkConstraints(partnerNodes, internalNodes)
log.Info().Msg("")

Expand Down Expand Up @@ -162,7 +163,7 @@ func finalize(cmd *cobra.Command, args []string) {
// if no root commit is specified, bootstrap an empty execution state
if flagRootCommit == "0000000000000000000000000000000000000000000000000000000000000000" {
commit := generateEmptyExecutionState(
block.Header.ChainID,
block.Header,
intermediaryData.ExecutionStateConfig,
participants,
)
Expand Down Expand Up @@ -557,7 +558,7 @@ func readIntermediaryBootstrappingData() (*IntermediaryBootstrappingData, *flow.
// generateEmptyExecutionState generates a new empty execution state with the
// given configuration. Sets the flagRootCommit variable for future reads.
func generateEmptyExecutionState(
chainID flow.ChainID,
rootBlock *flow.Header,
epochConfig epochs.EpochConfig,
identities flow.IdentityList,
) (commit flow.StateCommitment) {
Expand All @@ -577,7 +578,8 @@ func generateEmptyExecutionState(
commit, err = run.GenerateExecutionState(
filepath.Join(flagOutdir, model.DirnameExecutionState),
serviceAccountPublicKey,
chainID.Chain(),
rootBlock.ChainID.Chain(),
fvm.WithRootBlock(rootBlock),
fvm.WithInitialTokenSupply(cdcInitialTokenSupply),
fvm.WithMinimumStorageReservation(fvm.DefaultMinimumStorageReservation),
fvm.WithAccountCreationFee(fvm.DefaultAccountCreationFee),
Expand All @@ -591,3 +593,44 @@ func generateEmptyExecutionState(
log.Info().Msg("")
return commit
}

// validateOrPopulateEpochTimingConfig validates the epoch timing config flags. In case the
// `flagUseDefaultEpochTargetEndTime` value has been set, the function derives the values for
// `flagEpochTimingRefCounter`, `flagEpochTimingDuration`, and `flagEpochTimingRefTimestamp`
// from the configuration. Otherwise, it enforces that compatible values for the respective parameters have been
// specified (and errors otherwise). Therefore, after `validateOrPopulateEpochTimingConfig` ran,
// the targeted end time for the epoch can be computed via `rootEpochTargetEndTime()`.
// You can either let the tool choose default values, or specify a value for each config.
func validateOrPopulateEpochTimingConfig() error {
// Default timing is intended for Benchnet, Localnet, etc.
// Manually specified timings for Mainnet, Testnet, Canary.
if flagUseDefaultEpochTargetEndTime {
// No other flags may be set
if !(flagEpochTimingRefTimestamp == 0 && flagEpochTimingDuration == 0 && flagEpochTimingRefCounter == 0) {
return fmt.Errorf("invalid epoch timing config: cannot specify ANY of --epoch-timing-ref-counter, --epoch-timing-ref-timestamp, or --epoch-timing-duration if using default timing config")
}
flagEpochTimingRefCounter = flagEpochCounter
flagEpochTimingDuration = flagNumViewsInEpoch
flagEpochTimingRefTimestamp = uint64(time.Now().Unix()) + flagNumViewsInEpoch

// compute target end time for initial (root) epoch from flags: `TargetEndTime = RefTimestamp + (RootEpochCounter - RefEpochCounter) * Duration`
rootEpochTargetEndTimeUNIX := rootEpochTargetEndTime()
rootEpochTargetEndTime := time.Unix(int64(rootEpochTargetEndTimeUNIX), 0)
log.Info().Msgf("using default epoch timing config with root epoch target end time %s, which is in %s", rootEpochTargetEndTime, time.Until(rootEpochTargetEndTime))
} else {
// All other flags must be set
// NOTE: it is valid for flagEpochTimingRefCounter to be set to 0
if flagEpochTimingRefTimestamp == 0 || flagEpochTimingDuration == 0 {
return fmt.Errorf("invalid epoch timing config: must specify ALL of --epoch-timing-ref-counter, --epoch-timing-ref-timestamp, and --epoch-timing-duration")
}
if flagEpochCounter < flagEpochTimingRefCounter {
return fmt.Errorf("invalid epoch timing config: reference epoch counter must be less than or equal to root epoch counter")
}

// compute target end time for initial (root) epoch from flags: `TargetEndTime = RefTimestamp + (RootEpochCounter - RefEpochCounter) * Duration`
rootEpochTargetEndTimeUNIX := rootEpochTargetEndTime()
rootEpochTargetEndTime := time.Unix(int64(rootEpochTargetEndTimeUNIX), 0)
log.Info().Msgf("using user-specified epoch timing config with root epoch target end time %s, which is in %s", rootEpochTargetEndTime, time.Until(rootEpochTargetEndTime))
}
return nil
}
52 changes: 51 additions & 1 deletion cmd/bootstrap/cmd/finalize_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package cmd

import (
"encoding/hex"
"fmt"
"math/rand"
"path/filepath"
"regexp"
"strings"
Expand All @@ -23,7 +25,7 @@ const finalizeHappyPathLogs = "collecting partner network and staking keys" +
`read \d+ internal private node-info files` +
`read internal node configurations` +
`read \d+ weights for internal nodes` +
`checking constraints on consensus/cluster nodes` +
`checking constraints on consensus nodes` +
`assembling network and staking keys` +
`reading root block data` +
`reading root block votes` +
Expand Down Expand Up @@ -72,6 +74,10 @@ func TestFinalize_HappyPath(t *testing.T) {
flagNumViewsInStakingAuction = 50_000
flagNumViewsInDKGPhase = 2_000
flagEpochCommitSafetyThreshold = 1_000
flagUseDefaultEpochTargetEndTime = true
flagEpochTimingRefCounter = 0
flagEpochTimingRefTimestamp = 0
flagEpochTimingDuration = 0

// rootBlock will generate DKG and place it into bootDir/public-root-information
rootBlock(nil, nil)
Expand All @@ -85,6 +91,7 @@ func TestFinalize_HappyPath(t *testing.T) {
log = log.Hook(hook)

finalize(nil, nil)
fmt.Println(hook.logs.String())
assert.Regexp(t, finalizeHappyPathRegex, hook.logs.String())
hook.logs.Reset()

Expand Down Expand Up @@ -117,6 +124,49 @@ func TestClusterAssignment(t *testing.T) {
flagCollectionClusters = tmp
}

func TestEpochTimingConfig(t *testing.T) {
// Reset flags after test is completed
defer func(_flagDefault bool, _flagRefCounter, _flagRefTs, _flagDur uint64) {
flagUseDefaultEpochTargetEndTime = _flagDefault
flagEpochTimingRefCounter = _flagRefCounter
flagEpochTimingRefTimestamp = _flagRefTs
flagEpochTimingDuration = _flagDur
}(flagUseDefaultEpochTargetEndTime, flagEpochTimingRefCounter, flagEpochTimingRefTimestamp, flagEpochTimingDuration)

flags := []*uint64{&flagEpochTimingRefCounter, &flagEpochTimingRefTimestamp, &flagEpochTimingDuration}
t.Run("if default is set, no other flag may be set", func(t *testing.T) {
flagUseDefaultEpochTargetEndTime = true
for _, flag := range flags {
*flag = rand.Uint64()%100 + 1
err := validateOrPopulateEpochTimingConfig()
assert.Error(t, err)
*flag = 0 // set the flag back to 0
}
err := validateOrPopulateEpochTimingConfig()
assert.NoError(t, err)
})

t.Run("if default is not set, all other flags must be set", func(t *testing.T) {
flagUseDefaultEpochTargetEndTime = false
// First set all required flags and ensure validation passes
flagEpochTimingRefCounter = rand.Uint64() % flagEpochCounter
flagEpochTimingDuration = rand.Uint64()%100_000 + 1
flagEpochTimingRefTimestamp = rand.Uint64()

err := validateOrPopulateEpochTimingConfig()
assert.NoError(t, err)

// Next, check that validation fails if any one flag is not set
// NOTE: we do not include refCounter here, because it is allowed to be zero.
for _, flag := range []*uint64{&flagEpochTimingRefTimestamp, &flagEpochTimingDuration} {
*flag = 0
err := validateOrPopulateEpochTimingConfig()
assert.Error(t, err)
*flag = rand.Uint64()%100 + 1 // set the flag back to a non-zero value
}
})
}

// Check about the number of internal/partner nodes in each cluster. The identites
// in each cluster do not matter for this check.
func checkClusterConstraint(clusters flow.ClusterList, partnersInfo []model.NodeInfo, internalsInfo []model.NodeInfo) bool {
Expand Down
28 changes: 28 additions & 0 deletions cmd/bootstrap/cmd/rootblock.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ var (
flagNumViewsInEpoch uint64
flagNumViewsInStakingAuction uint64
flagNumViewsInDKGPhase uint64
// Epoch target end time config
flagUseDefaultEpochTargetEndTime bool
flagEpochTimingRefCounter uint64
flagEpochTimingRefTimestamp uint64
flagEpochTimingDuration uint64
)

// rootBlockCmd represents the rootBlock command
Expand Down Expand Up @@ -95,6 +100,25 @@ func addRootBlockCmdFlags() {
cmd.MarkFlagRequired(rootBlockCmd, "root-height")
cmd.MarkFlagRequired(rootBlockCmd, "protocol-version")
cmd.MarkFlagRequired(rootBlockCmd, "epoch-commit-safety-threshold")

// Epoch timing config - these values must be set identically to `EpochTimingConfig` in the FlowEpoch smart contract.
// See https://github.com/onflow/flow-core-contracts/blob/240579784e9bb8d97d91d0e3213614e25562c078/contracts/epochs/FlowEpoch.cdc#L259-L266
// Must specify either:
// 1. --use-default-epoch-timing and no other `--epoch-timing*` flags
// 2. All `--epoch-timing*` flags except --use-default-epoch-timing
//
// Use Option 1 for Benchnet, Localnet, etc.
// Use Option 2 for Mainnet, Testnet, Canary.
rootBlockCmd.Flags().BoolVar(&flagUseDefaultEpochTargetEndTime, "use-default-epoch-timing", false, "whether to use the default target end time")
rootBlockCmd.Flags().Uint64Var(&flagEpochTimingRefCounter, "epoch-timing-ref-counter", 0, "the reference epoch for computing the root epoch's target end time")
rootBlockCmd.Flags().Uint64Var(&flagEpochTimingRefTimestamp, "epoch-timing-ref-timestamp", 0, "the end time of the reference epoch, specified in second-precision Unix time, to use to compute the root epoch's target end time")
rootBlockCmd.Flags().Uint64Var(&flagEpochTimingDuration, "epoch-timing-duration", 0, "the duration of each epoch in seconds, used to compute the root epoch's target end time")

rootBlockCmd.MarkFlagsOneRequired("use-default-epoch-timing", "epoch-timing-ref-counter", "epoch-timing-ref-timestamp", "epoch-timing-duration")
rootBlockCmd.MarkFlagsRequiredTogether("epoch-timing-ref-counter", "epoch-timing-ref-timestamp", "epoch-timing-duration")
for _, flag := range []string{"epoch-timing-ref-counter", "epoch-timing-ref-timestamp", "epoch-timing-duration"} {
rootBlockCmd.MarkFlagsMutuallyExclusive("use-default-epoch-timing", flag)
}
}

func rootBlock(cmd *cobra.Command, args []string) {
Expand All @@ -114,6 +138,10 @@ func rootBlock(cmd *cobra.Command, args []string) {
if err != nil {
log.Fatal().Err(err).Msg("invalid or unsafe epoch commit threshold config")
}
err = validateOrPopulateEpochTimingConfig()
if err != nil {
log.Fatal().Err(err).Msg("invalid epoch timing config")
}

log.Info().Msg("collecting partner network and staking keys")
partnerNodes := readPartnerNodeInfos()
Expand Down
4 changes: 4 additions & 0 deletions cmd/bootstrap/cmd/rootblock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ func TestRootBlock_HappyPath(t *testing.T) {
flagNumViewsInDKGPhase = 2_000
flagEpochCommitSafetyThreshold = 1_000
flagProtocolVersion = 42
flagUseDefaultEpochTargetEndTime = true
flagEpochTimingRefCounter = 0
flagEpochTimingRefTimestamp = 0
flagEpochTimingDuration = 0

hook := zeroLoggerHook{logs: &strings.Builder{}}
log = log.Hook(hook)
Expand Down
20 changes: 20 additions & 0 deletions cmd/bootstrap/cmd/seal.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"encoding/hex"
"time"

"github.com/onflow/flow-go/cmd/bootstrap/run"
"github.com/onflow/flow-go/model/flow"
Expand Down Expand Up @@ -38,3 +39,22 @@ func constructRootResultAndSeal(

return result, seal
}

// rootEpochTargetEndTime computes the target end time for the given epoch, using the given config.
// CAUTION: the variables `flagEpochTimingRefCounter`, `flagEpochTimingDuration`, and
// `flagEpochTimingRefTimestamp` must contain proper values. You can either specify a value for
// each config parameter or use the function `validateOrPopulateEpochTimingConfig()` to populate the variables
// from defaults.
func rootEpochTargetEndTime() uint64 {
if flagEpochTimingRefTimestamp == 0 || flagEpochTimingDuration == 0 {
panic("invalid epoch timing config: must specify ALL of --epoch-target-end-time-ref-counter, --epoch-target-end-time-ref-timestamp, and --epoch-target-end-time-duration")
}
if flagEpochCounter < flagEpochTimingRefCounter {
panic("invalid epoch timing config: reference epoch counter must be less than or equal to root epoch counter")
}
targetEndTime := flagEpochTimingRefTimestamp + (flagEpochCounter-flagEpochTimingRefCounter)*flagEpochTimingDuration
if targetEndTime <= uint64(time.Now().Unix()) {
panic("sanity check failed: root epoch target end time is before current time")
}
return targetEndTime
}
10 changes: 0 additions & 10 deletions cmd/consensus/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ func main() {
emergencySealing bool
dkgMessagingEngineConfig = dkgeng.DefaultMessagingEngineConfig()
cruiseCtlConfig = cruisectl.DefaultConfig()
cruiseCtlTargetTransitionTimeFlag = cruiseCtlConfig.TargetTransition.String()
cruiseCtlFallbackProposalDurationFlag time.Duration
cruiseCtlMinViewDurationFlag time.Duration
cruiseCtlMaxViewDurationFlag time.Duration
Expand Down Expand Up @@ -148,7 +147,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 All @@ -174,14 +172,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
3 changes: 3 additions & 0 deletions cmd/scaffold.go
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,7 @@ func (fnb *FlowNodeBuilder) initFvmOptions() {

// handleModules initializes the given module.
func (fnb *FlowNodeBuilder) handleModule(v namedModuleFunc) error {
fnb.Logger.Info().Str("module", v.name).Msg("module initialization started")
err := v.fn(fnb.NodeConfig)
if err != nil {
return fmt.Errorf("module %s initialization failed: %w", v.name, err)
Expand Down Expand Up @@ -1398,6 +1399,7 @@ func (fnb *FlowNodeBuilder) handleComponent(v namedComponentFunc, dependencies <

logger := fnb.Logger.With().Str("component", v.name).Logger()

logger.Info().Msg("component initialization started")
// First, build the component using the factory method.
readyAware, err := v.fn(fnb.NodeConfig)
if err != nil {
Expand Down Expand Up @@ -1469,6 +1471,7 @@ func (fnb *FlowNodeBuilder) handleRestartableComponent(v namedComponentFunc, par

// This may be called multiple times if the component is restarted
componentFactory := func() (component.Component, error) {
log.Info().Msg("component initialization started")
c, err := v.fn(fnb.NodeConfig)
if err != nil {
return nil, err
Expand Down
File renamed without changes.
Loading

0 comments on commit 533571f

Please sign in to comment.