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

test(e2e): fix proposer selection test #926

Merged
merged 8 commits into from
Sep 26, 2024
Merged

test(e2e): fix proposer selection test #926

merged 8 commits into from
Sep 26, 2024

Conversation

lklimek
Copy link
Collaborator

@lklimek lklimek commented Sep 20, 2024

Issue being fixed or feature implemented

e2e tests fail due to new proposer selection algorithm

What was done?

  1. Fixed proposer selection logic in validator_test.go to support consensus version 0 and 1 algorithm
  2. Implemented support for changing consensus version in e2e app
  3. Run TestApp_TxTooBig on just one node, to avoid timeouts

In future, we might also introduce vote rejection logic to e2e tests, to emulate increasing rounds.

How Has This Been Tested?

CI/CD passed.

Breaking Changes

None

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

Summary by CodeRabbit

  • New Features

    • Introduced consensus version updates functionality in the configuration, enhancing management of consensus parameters.
    • Added new sections in configuration files for validator and consensus version updates.
  • Bug Fixes

    • Improved logic for validator selection and block proposing in tests, enhancing robustness.
  • Tests

    • Enhanced test logic for processing consensus version updates, ensuring efficiency and accuracy.
    • Implemented limits on block fetching during tests to prevent excessive durations.

Copy link
Contributor

coderabbitai bot commented Sep 25, 2024

Walkthrough

The changes introduce a new configuration capability to manage consensus version updates across various components of the application. This includes adding fields to multiple structs, modifying functions to handle these updates, and enhancing configuration files to reflect the new consensus versioning structure. The updates aim to streamline the management of consensus parameters and improve the organization of related settings within the application.

Changes

File Path Change Summary
abci/example/kvstore/config.go Added field ConsensusVersionUpdates map[string]int32 to Config struct for managing consensus version updates.
test/e2e/app/app.go Introduced logic in NewApplication to process consensus version updates from configuration, creating ConsensusParams objects.
test/e2e/node/config.go Added field ConsensusVersionUpdates map[string]int32 to Config struct and updated App method to include it.

Sequence Diagram(s)

sequenceDiagram
    participant Config
    participant App

    Config->>App: Add ConsensusVersionUpdates
    App->>App: Process ConsensusVersionUpdates
    App->>App: Create ConsensusParams
    App-->>Config: Return Updated Configuration
Loading

🐇 In the fields where we hop,
New versions rise, they never stop.
With maps and updates, oh so bright,
Our consensus shines, a joyful sight!
Let's leap ahead, with code so neat,
In our burrow, we can't be beat! 🌟


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between b3163c6 and 7a3df71.

📒 Files selected for processing (3)
  • abci/example/kvstore/config.go (1 hunks)
  • test/e2e/app/app.go (2 hunks)
  • test/e2e/node/config.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • abci/example/kvstore/config.go
  • test/e2e/app/app.go
  • test/e2e/node/config.go

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@lklimek lklimek marked this pull request as ready for review September 25, 2024 14:24
@lklimek
Copy link
Collaborator Author

lklimek commented Sep 25, 2024

@coderabbitai review

Copy link
Contributor

coderabbitai bot commented Sep 25, 2024

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

🧹 Outside diff range and nitpick comments (10)
test/e2e/tests/e2e_test.go (2)

129-132: LGTM: Effective implementation of block limit.

The changes effectively implement the block limit using the maxBlocks constant. This will help prevent excessively long test durations as intended.

Consider adding a comment explaining why to is adjusted instead of from. For example:

 // limit blocks to fetch to avoid long test times
 if to-from > maxBlocks {
+    // Adjust 'to' to fetch the most recent blocks within the limit
     to = from + maxBlocks
 }

This clarifies the decision to fetch the most recent blocks when limiting the range.


Line range hint 19-132: Overall assessment: Well-implemented optimization for e2e tests.

The changes effectively address the potential issue of long-running tests by limiting the number of blocks fetched. The implementation is clean, well-commented, and doesn't introduce any breaking changes.

Consider adding a test case that specifically verifies the behavior when the number of blocks exceeds maxBlocks. This would ensure that the limiting logic works as expected under various conditions.

abci/example/kvstore/config.go (2)

73-74: Implement or document usage of ConsenusVersionUpdates

The new ConsenusVersionUpdates field is not used anywhere else in this file. Consider the following suggestions:

  1. If the implementation is in other files, it would be helpful to add a comment indicating where the field is used or processed.

  2. If the implementation is pending, consider adding a TODO comment to remind about implementing the logic for handling consensus version updates.

  3. It might be beneficial to update the validatorSetUpdates method or add a new method to handle the consensus version updates, ensuring that the new configuration option is properly integrated into the application's logic.

Example:

// TODO: Implement handling of ConsensusVersionUpdates in processConsensusParams method

Line range hint 1-74: Consider grouping related fields in the Config struct

The Config struct contains various fields for different aspects of the application. To improve readability and maintainability, consider grouping related fields together. Here's a suggested reorganization:

  1. Basic configuration:

    • Dir
    • KeyType
  2. Block and state management:

    • RetainBlocks
    • PersistInterval
    • SnapshotInterval
  3. Validator management:

    • ValidatorUpdates
    • ThesholdPublicKeyUpdate
    • QuorumHashUpdate
  4. Performance simulation:

    • PrepareProposalDelayMS
    • ProcessProposalDelayMS
    • CheckTxDelayMS
    • VoteExtensionDelayMS
    • FinalizeBlockDelayMS
  5. Dash-specific parameters:

    • ChainLockUpdates
    • PrivValServerType
    • InitAppInitialCoreHeight
  6. Testing and versioning:

    • ConsensusVersionUpdates (after fixing the typo)

Adding comments to separate these groups would further enhance the struct's readability.

test/e2e/tests/app_test.go (2)

254-260: LGTM with a suggestion: Add a safety check for non-stateless nodes.

The logic to find the first non-stateless node is a good optimization. However, it assumes that at least one non-stateless node exists.

Consider adding a check to ensure that a non-stateless node was found:

 for _, node = range nodes {
   if !node.Stateless() {
     break
   }
 }
+if node == nil || node.Stateless() {
+  t.Fatal("No non-stateless node found in the testnet")
+}

276-307: LGTM with a suggestion: Consider parameterizing the number of transactions.

The changes in this section are well-structured and effectively test the scenario of transactions exceeding block size. The calculation of transaction size based on block parameters is a good approach for maintaining test validity across different configurations.

Consider making the number of transactions (currently hardcoded as 101) a parameter or a constant at the top of the file. This would make it easier to adjust the test conditions if needed:

+const numTxsForBigTxTest = 101

 // ... (in the test function)
-numTxs := 101
+numTxs := numTxsForBigTxTest
test/e2e/pkg/manifest.go (1)

59-65: LGTM! Consider enhancing the comment for clarity.

The addition of the ConsensusVersionUpdates field is well-implemented and aligns with the PR objectives. It provides a flexible way to specify consensus version changes at different heights.

Consider slightly modifying the comment to clarify that this is for test scenarios:

- // ConsensusVersionUpdates is a map of heights to consensus versions, and
- // will be sent by the ABCI application as a consensus params update.
+ // ConsensusVersionUpdates is a map of heights to consensus versions for testing, and
+ // will be sent by the ABCI application as a consensus params update in test scenarios.

This change emphasizes that this field is specifically for testing purposes and not for production use.

test/e2e/pkg/testnet.go (1)

453-459: LGTM with suggestion: ConsensusVersionUpdates population logic

The logic for populating the ConsensusVersionUpdates map is correct and includes proper error handling for invalid height strings. However, consider adding validation for the consensus version value (cpUpdate) to ensure it's within an expected range or meets certain criteria.

Consider adding validation for cpUpdate, for example:

 for heightStr, cpUpdate := range manifest.ConsensusVersionUpdates {
     height, err := strconv.Atoi(heightStr)
     if err != nil {
         return nil, fmt.Errorf("invalid consensus version update height %q: %w", height, err)
     }
+    if cpUpdate < 0 {
+        return nil, fmt.Errorf("invalid consensus version %d at height %d: must be non-negative", cpUpdate, height)
+    }
     testnet.ConsensusVersionUpdates[int64(height)] = cpUpdate
 }
test/e2e/app/app.go (1)

66-68: Error handling could leak sensitive information

Including the original error err in the formatted error message might expose internal details. Consider sanitizing the error message before returning it.

Suggested change:

-			return nil, fmt.Errorf("consensus_version_updates: failed to parse height %s: %w", h, err)
+			return nil, fmt.Errorf("consensus_version_updates: failed to parse height %s", h)
test/e2e/tests/validator_test.go (1)

Line range hint 239-283: Refactor nested conditional logic in the Increment method

The Increment method contains deeply nested if statements from lines 251 to 276, which can make the code harder to read and maintain.

Consider refactoring the nested conditionals to improve readability. Using guard clauses or early returns can flatten the structure. Here's an example:

func (s *validatorSchedule) Increment(heights int64) error {
    for i := int64(0); i < heights; i++ {
        s.height++

        // Consensus params update
        s.consensusVersionUpdate()
        cp := s.ConsensusParams()

        // Validator set update
        if s.height <= 1 {
            continue
        }

        // Validator set updates are offset by 1
        update, ok := s.updates[s.height-1]
        if !ok {
            continue
        }

        thresholdPublicKeyUpdate, ok := s.thresholdPublicKeyUpdates[s.height-1]
        if !ok {
            continue
        }

        quorumHashUpdate, ok := s.quorumHashUpdates[s.height-1]
        if !ok {
            continue
        }

        currentQuorumHash := s.ValidatorProposer.ValidatorSet().QuorumHash
        if bytes.Equal(quorumHashUpdate, currentQuorumHash) {
            vs := s.ValidatorProposer.ValidatorSet()
            if err := vs.UpdateWithChangeSet(makeVals(update), thresholdPublicKeyUpdate, quorumHashUpdate); err != nil {
                return err
            }
        } else {
            vs := types.NewValidatorSet(makeVals(update), thresholdPublicKeyUpdate, btcjson.LLMQType_5_60, quorumHashUpdate, true)
            ps, err := selectproposer.NewProposerSelector(cp, vs, s.height, 0, nil, nil)
            if err != nil {
                return err
            }
            if cp.Version.ConsensusVersion == 0 {
                // Consensus version 0 had an issue where the first proposer didn't propose
                ps.ValidatorSet().IncProposerIndex(1)
            }
            s.ValidatorProposer = ps
        }

        if err := s.ValidatorProposer.UpdateHeightRound(s.height, 0); err != nil {
            return err
        }
    }
    return nil
}

This refactoring eliminates unnecessary nesting by checking conditions upfront and continuing to the next iteration if they're not met. This approach improves code readability and maintainability.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between aebd750 and b3163c6.

📒 Files selected for processing (10)
  • abci/example/kvstore/config.go (1 hunks)
  • test/e2e/app/app.go (2 hunks)
  • test/e2e/networks/rotate.toml (1 hunks)
  • test/e2e/node/config.go (2 hunks)
  • test/e2e/pkg/manifest.go (1 hunks)
  • test/e2e/pkg/testnet.go (3 hunks)
  • test/e2e/runner/setup.go (1 hunks)
  • test/e2e/tests/app_test.go (1 hunks)
  • test/e2e/tests/e2e_test.go (2 hunks)
  • test/e2e/tests/validator_test.go (8 hunks)
🔇 Additional comments not posted (12)
test/e2e/node/config.go (1)

Line range hint 1-85: Verify LoadConfig function and update documentation

The changes look good overall, but there are a couple of things to consider:

  1. Verify that the LoadConfig function (not visible in this diff) correctly handles the new ConsensusVersionUpdates field when loading from a TOML file.

  2. Consider updating any relevant documentation (e.g., comments, README, or separate documentation files) to reflect the new ConsensusVersionUpdates configuration option.

To check if the LoadConfig function needs updating, you can run:

Ensure that any components relying on this configuration are updated to handle the new consensus version updates appropriately.

test/e2e/tests/e2e_test.go (1)

19-21: LGTM: Well-defined constant with clear purpose.

The introduction of maxBlocks is a good approach to limit the number of blocks fetched during testing, which can help prevent excessively long test durations. The constant is well-named and its purpose is clearly explained in the comments.

test/e2e/networks/rotate.toml (4)

84-89: LGTM: Validator update at height 1070 looks good.

The new validator update section for height 1070 is consistent with the existing pattern in the file. It correctly assigns equal voting power (100) to validators 01 through 05.


92-97: LGTM: Validator update at height 1077 introduces a new validator set.

The new validator update section for height 1077 is consistent with the existing pattern. It correctly assigns equal voting power (100) to validators 01, 07, 08, 10, and 11. This update changes the validator set compared to the previous update at height 1070, which is likely intentional for testing purposes.


83-104: Summary: New sections align well with PR objectives.

The additions to the rotate.toml file, including new validator update sections and the consensus version updates section, align well with the PR objectives. These changes provide more granular control over validator sets and consensus versions, which should facilitate testing of the new proposer selection algorithm and support for both consensus version 0 and 1.

The new sections are consistent with the existing file structure and appear to be well-integrated. They should contribute to more comprehensive end-to-end testing scenarios.


99-103: New consensus version updates section added. Please clarify the meaning of values.

The new [consensus_version_updates] section is a valuable addition for testing consensus version changes. The updates are well-aligned with the validator update heights. However, the meaning of the values (0 and 1) is not immediately clear from the context.

Could you please add a comment explaining what these values represent? For example, do they correspond to specific consensus versions or indicate whether an update should occur?

To ensure consistency and completeness, let's check if there are any other occurrences of consensus version updates in the file:

✅ Verification successful

Consensus version updates section verified.

The [consensus_version_updates] section is unique within the test/e2e/networks/rotate.toml file, with no other occurrences found.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other occurrences of consensus version updates
rg --type toml 'consensus.*version' test/e2e/networks/rotate.toml

Length of output: 95

test/e2e/tests/app_test.go (3)

246-253: LGTM: Improved context handling for transaction broadcasting.

The addition of a timeout context and the check for context cancellation before broadcasting are good practices. These changes enhance the control over the operation's duration and prevent unnecessary work.


308-308: LGTM: Improved test efficiency by removing redundant code.

The removal of code that was broadcasting to all nodes and the establishment of the broadcasting context outside the loop are good improvements. These changes align with the new approach of using a single node and likely enhance the test's efficiency.


Line range hint 1-1: Overall assessment: Good improvements to the TestApp_TxTooBig function.

The changes to this file, particularly in the TestApp_TxTooBig function, have significantly improved the test's efficiency and robustness. The new approach of using a single non-stateless node, improved context handling, and better transaction size calculation are all positive changes.

There are a few minor suggestions for further improvement:

  1. Add a safety check for the existence of non-stateless nodes.
  2. Consider addressing the issue with ConsensusParams for the last height.
  3. Parameterize the number of transactions used in the test.

These changes have enhanced the test's ability to verify the behavior of submitting transactions larger than the block size, which is crucial for ensuring the correct functioning of the blockchain application under various conditions.

test/e2e/runner/setup.go (1)

441-447: Summary: Consensus version updates support added successfully

The changes introduced in this file successfully implement support for consensus version updates in the testnet configuration. This addition aligns well with the PR objectives and enhances the flexibility of the testing framework.

Key points:

  1. The implementation correctly handles the conversion of consensus version updates to the required format.
  2. The new configuration is integrated seamlessly into the existing MakeAppConfig function.
  3. The changes are localized and don't introduce any breaking changes to the existing codebase.

These modifications will allow for more comprehensive testing of consensus version changes in the e2e test suite.

test/e2e/pkg/testnet.go (2)

105-106: LGTM: ConsensusVersionUpdates field addition

The addition of the ConsensusVersionUpdates field to the Testnet struct is a good approach for managing consensus version updates at specific heights. The use of int64 for height and int32 for version is appropriate and consistent with common practices.


221-221: LGTM: ConsensusVersionUpdates map initialization

The initialization of the ConsensusVersionUpdates map is correct and consistent with the initialization of other similar fields in the Testnet struct.

test/e2e/node/config.go Outdated Show resolved Hide resolved
test/e2e/node/config.go Outdated Show resolved Hide resolved
abci/example/kvstore/config.go Outdated Show resolved Hide resolved
test/e2e/tests/app_test.go Show resolved Hide resolved
test/e2e/pkg/manifest.go Show resolved Hide resolved
test/e2e/runner/setup.go Show resolved Hide resolved
test/e2e/app/app.go Outdated Show resolved Hide resolved
test/e2e/app/app.go Show resolved Hide resolved
test/e2e/app/app.go Show resolved Hide resolved
test/e2e/tests/validator_test.go Show resolved Hide resolved
@lklimek lklimek merged commit 005af92 into v1.3-dev Sep 26, 2024
16 checks passed
@lklimek lklimek deleted the test/e2e-proposer branch September 26, 2024 13:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

2 participants