Add simple finality itest#2063
Conversation
Simple two node finality test added.
Ordering of commitments state hash records fixed with new key.
dfa1861 to
4d4bd2d
Compare
Updated genesis.json configuration to support go/scala/no -mining. Enabled log level check added before querying latest finalized block height.
There was a problem hiding this comment.
Pull request overview
Adds a smoke integration test around deterministic finality (feature activation + commit-to-generation workflow across Go/Scala nodes) and adjusts supporting state-hash/config plumbing to make the scenario reproducible in itests.
Changes:
- Add a new
smokeitest suite for finality and introduce a dedicated feature settings JSON enabling finality support. - Update itests genesis/config plumbing to distinguish Go vs Scala mining key derivation (
mining_type) and to pass generation-period length into node configs. - Adjust commitments state-hash keying to avoid overwriting hashed components when multiple commitments are stored.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/state/state.go | Adds info-level logging around finalization state during block apply. |
| pkg/state/keys.go | Introduces a special key type used for ordering/uniqueness in commitment state-hash tracking. |
| pkg/state/commitments.go | Adds lastIndex() and uses an indexed key for state-hash pushes when storing commitments. |
| itests/testdata/feature_settings/finality_supported_setting.json | New feature settings enabling deterministic finality support in itests. |
| itests/smoke_finality_internal_test.go | New smoke suite that commits to generation periods after finality activation. |
| itests/init_internal_test.go | Forces Docker client API version via environment variables during test setup. |
| itests/finality_internal_test.go | Renames wallet address constants and adds a Scala miner address constant. |
| itests/docker/docker.go | Also forces Docker client API version via environment variables in Docker helper. |
| itests/config/template.conf | Passes generation-period-length into the node configuration template. |
| itests/config/miningtype.go | Adds MiningType enum with go:generate for string/JSON helpers. |
| itests/config/miningtype_string.go | Generated enum string/JSON marshaling code for MiningType. |
| itests/config/genesis_settings.go | Switches genesis distribution from is_miner to mining_type and derives BLS keys differently for Go vs Scala mining. |
| itests/config/genesis.json | Updates genesis distributions to use mining_type and reformats preactivated features. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Set environment variables to enforce docker client connection with a required API version. | ||
| // Non-empty DOCKER_MACHINE_NAME allows to create client with DOCKER_API_VERSION. | ||
| if envErr := os.Setenv("DOCKER_MACHINE_NAME", "local"); envErr != nil { | ||
| return envErr | ||
| } | ||
| if envErr := os.Setenv("DOCKER_API_VERSION", "1.45"); envErr != nil { | ||
| return envErr | ||
| } |
There was a problem hiding this comment.
testsSetup() unconditionally overwrites DOCKER_MACHINE_NAME and DOCKER_API_VERSION for the whole process. This can break users/CI that intentionally set these variables (or rely on Docker’s negotiated API version). Consider only setting them when they are not already set (via os.LookupEnv) and/or centralizing this logic in one place (it’s duplicated in itests/docker.NewDocker).
There was a problem hiding this comment.
Added a function to check for an environment variable and set it only if it is not already defined.
| if slog.Default().Enabled(context.Background(), slog.LevelInfo) { | ||
| finalizedHeight, err := s.stor.finality.lastFinalizedHeight(blockHeight) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to build local endorsement message: %w", err) | ||
| } | ||
| slog.Info("Current finalization state", slog.Uint64("finalizedHeight", finalizedHeight), |
There was a problem hiding this comment.
This changes the finalization log from slog.Debug to an Info log executed for every block while DeterministicFinality is active. That can produce very high log volume in normal runs; consider keeping it at debug (or sampling/throttling) and/or using Enabled(..., slog.LevelDebug) to avoid expensive lookups without increasing default verbosity.
| if slog.Default().Enabled(context.Background(), slog.LevelInfo) { | |
| finalizedHeight, err := s.stor.finality.lastFinalizedHeight(blockHeight) | |
| if err != nil { | |
| return fmt.Errorf("failed to build local endorsement message: %w", err) | |
| } | |
| slog.Info("Current finalization state", slog.Uint64("finalizedHeight", finalizedHeight), | |
| if slog.Default().Enabled(context.Background(), slog.LevelDebug) { | |
| finalizedHeight, err := s.stor.finality.lastFinalizedHeight(blockHeight) | |
| if err != nil { | |
| return fmt.Errorf("failed to build local endorsement message: %w", err) | |
| } | |
| slog.Debug("Current finalization state", slog.Uint64("finalizedHeight", finalizedHeight), |
There was a problem hiding this comment.
Nope, this is ok.
There was a problem hiding this comment.
Guess the Enabled check is redundant here, because users mostly use logger at INFO level. What do you think?
Function to retrieve and compare finalized blocks heights added and called in test.
| // commitmentStateHashKey is used only to correctly order legacy state hash record. | ||
| // WARNING! Do not use the key for any storage operations. |
There was a problem hiding this comment.
Maybe move it to a new file? (state_hasher_keys.go, for example)
| if slog.Default().Enabled(context.Background(), slog.LevelInfo) { | ||
| finalizedHeight, err := s.stor.finality.lastFinalizedHeight(blockHeight) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to build local endorsement message: %w", err) | ||
| } | ||
| slog.Info("Current finalization state", slog.Uint64("finalizedHeight", finalizedHeight), |
There was a problem hiding this comment.
Guess the Enabled check is redundant here, because users mostly use logger at INFO level. What do you think?
Section about env vars added to itest README.
No description provided.