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

refactor(zetacore): delete ballots after maturity #2863

Open
wants to merge 19 commits into
base: develop
Choose a base branch
from

Conversation

kingpinXD
Copy link
Contributor

@kingpinXD kingpinXD commented Sep 11, 2024

Description

Closes #942

The PR does the following

  • Adds logic to delete matured ballots automatically
  • Adds a migration script to delete older matured ballots to clean up the state
  • Adds a new query to enable query of all ballots

How Has This Been Tested?

  • Tested CCTX in localnet
  • Tested in development environment
  • Go unit tests
  • Go integration tests
  • Tested via GitHub Actions

Summary by CodeRabbit

  • New Features

    • Added functionality to delete matured ballots, enhancing ballot lifecycle management.
    • Introduced a new VoterList message type to track individual voter details.
    • Added event handling for deleted ballots to improve system responsiveness.
  • Bug Fixes

    • Enhanced logic for managing observer rewards and matured ballots.
  • Tests

    • Expanded test coverage for ballot deletion and voter list generation, ensuring robustness in functionality.
  • Documentation

    • Updated changelog to reflect the latest changes and features.

Copy link
Contributor

coderabbitai bot commented Sep 11, 2024

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough
📝 Walkthrough
📝 Walkthrough
📝 Walkthrough
📝 Walkthrough
📝 Walkthrough
📝 Walkthrough
📝 Walkthrough
📝 Walkthrough
📝 Walkthrough
📝 Walkthrough

Walkthrough

The changes introduced in this pull request focus on enhancing ballot management within the system, specifically addressing the deletion of matured ballots. This includes the addition of new message types, modifications to existing functions for handling ballots, and the introduction of event emissions upon ballot deletion. The updates aim to streamline the lifecycle management of ballots, ensuring that matured ballots are efficiently removed from the state to optimize resource use.

Changes

Files Change Summary
changelog.md Added entry for deleting ballots after they mature.
proto/zetachain/zetacore/observer/ballot.proto Introduced VoterList message with fields for voter address and vote type.
proto/zetachain/zetacore/observer/events.proto Added EventBallotDeleted message and imported ballot.proto.
proto/zetachain/zetacore/observer/query.proto Modified QueryBallotByIdentifierResponse to enforce non-nullable voters field.
testutil/keeper/mocks/emissions/observer.go Introduced ClearMaturedBallots mock function for testing.
x/emissions/abci.go Modified DistributeObserverRewards to handle and clear matured ballots.
x/emissions/abci_test.go Adjusted test logic for reward distribution and ballot maturity checks.
x/emissions/types/expected_keepers.go Added ClearMaturedBallots method to ObserverKeeper interface.
x/observer/keeper/ballot.go Added methods for deleting individual ballots and lists, and clearing matured ballots.
x/observer/keeper/ballot_test.go Added tests for deleting ballots, clearing matured ballots, and ensuring correct behavior.
x/observer/keeper/events.go Introduced EmitEventBallotDeleted for emitting deletion events.
x/observer/keeper/events_test.go Created tests for EmitEventBallotDeleted functionality.
x/observer/keeper/grpc_query_ballot.go Simplified voter list construction using GenerateVoterList method.
x/observer/keeper/grpc_query_ballot_test.go Changed Voters field type in response struct from pointer to value slice.
x/observer/types/ballot.go Added GenerateVoterList method to Ballot struct for generating voter lists.
x/observer/types/ballot_test.go Added tests for GenerateVoterList method to validate voter list generation.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Keeper
    participant EventManager

    User->>Keeper: Request to delete matured ballots
    Keeper->>Keeper: Identify matured ballots
    Keeper->>Keeper: Delete matured ballots
    Keeper->>EventManager: Emit EventBallotDeleted
    EventManager-->>Keeper: Confirmation of event emission
Loading

Assessment against linked issues

Objective Addressed Explanation
Delete matured ballots (##942)
Add an event when the ballot gets deleted (##942)

Possibly related PRs

Suggested labels

breaking:cli, chain:solana


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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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.

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.

Copy link

codecov bot commented Sep 11, 2024

Codecov Report

Attention: Patch coverage is 91.33858% with 11 lines in your changes missing coverage. Please review.

Project coverage is 61.79%. Comparing base (faf1f79) to head (e533f7e).
Report is 2 commits behind head on develop.

Files with missing lines Patch % Lines
x/observer/keeper/grpc_query_ballot.go 63.33% 7 Missing and 4 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #2863      +/-   ##
===========================================
+ Coverage    61.71%   61.79%   +0.07%     
===========================================
  Files          440      441       +1     
  Lines        31141    31235      +94     
===========================================
+ Hits         19220    19302      +82     
- Misses       11058    11066       +8     
- Partials       863      867       +4     
Files with missing lines Coverage Δ
x/emissions/abci.go 93.83% <100.00%> (+0.65%) ⬆️
x/observer/keeper/ballot.go 100.00% <100.00%> (ø)
x/observer/migrations/v9/migrate.go 100.00% <100.00%> (ø)
x/observer/types/ballot.go 100.00% <100.00%> (ø)
x/observer/keeper/grpc_query_ballot.go 80.32% <63.33%> (-19.68%) ⬇️

@kingpinXD kingpinXD changed the title Clear ballots refactor : delete balots after maturity Sep 11, 2024
@kingpinXD kingpinXD changed the title refactor : delete balots after maturity refactor: delete balots after maturity Sep 11, 2024
@kingpinXD kingpinXD marked this pull request as ready for review September 11, 2024 20:03
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: 4

Outside diff range and nitpick comments (6)
x/emissions/types/expected_keepers.go (1)

19-19: Consider enhancing the clarity and documentation of the ClearMaturedBallots method.

The addition of the ClearMaturedBallots method to the ObserverKeeper interface is a good change as it allows for the clearing of matured ballots. However, consider the following suggestions to improve the clarity and documentation of the method:

  1. Consider renaming the method to something more specific, such as RemoveMaturedBallotsFromState, to clearly indicate that it's removing the ballots from the state.

  2. Consider renaming the maturityBlocks parameter to a more descriptive name, such as maturityThreshold, to clarify its purpose.

  3. Add a comment above the method to explain its functionality and any important details about its usage. This will help future maintainers understand the purpose and behavior of the method.

x/observer/keeper/events_test.go (1)

15-37: Consider defining the test case struct outside the test function for better readability.

The test case struct is defined within the test function, which can make the test function harder to read. Consider moving the struct definition outside the test function.

-func TestEmitEventBallotDeleted(t *testing.T) {
-	tt := []struct {
-		name             string
-		ballotIdentifier string
-		ballotType       types.ObservationType
-		voters           []string
-		voteType         []types.VoteType
-	}{
-		{
-			name:             "successfull votes only",
-			ballotIdentifier: sample.ZetaIndex(t),
-			ballotType:       types.ObservationType_InboundTx,
-			voters:           []string{"voter1", "voter2"},
-			voteType:         []types.VoteType{types.VoteType_SuccessObservation, types.VoteType_SuccessObservation},
-		},
-		{
-			name:             "failed votes only",
-			ballotIdentifier: sample.ZetaIndex(t),
-			ballotType:       types.ObservationType_InboundTx,
-			voters:           []string{"voter1", "voter2"},
-			voteType:         []types.VoteType{types.VoteType_FailureObservation, types.VoteType_FailureObservation},
-		},
-	}
+type testCase struct {
+	name             string
+	ballotIdentifier string
+	ballotType       types.ObservationType
+	voters           []string
+	voteType         []types.VoteType
+}
+
+func TestEmitEventBallotDeleted(t *testing.T) {
+	tt := []testCase{
+		{
+			name:             "successfull votes only",
+			ballotIdentifier: sample.ZetaIndex(t),
+			ballotType:       types.ObservationType_InboundTx,
+			voters:           []string{"voter1", "voter2"},
+			voteType:         []types.VoteType{types.VoteType_SuccessObservation, types.VoteType_SuccessObservation},
+		},
+		{
+			name:             "failed votes only",
+			ballotIdentifier: sample.ZetaIndex(t),
+			ballotType:       types.ObservationType_InboundTx,
+			voters:           []string{"voter1", "voter2"},
+			voteType:         []types.VoteType{types.VoteType_FailureObservation, types.VoteType_FailureObservation},
+		},
+	}
x/observer/keeper/grpc_query_ballot_test.go (1)

Line range hint 127-132: Approved with Suggestions

The code changes are minimal and do not introduce any issues. However, consider the following suggestions to improve the code:

  1. Improve Error Handling: In the 3rd sub-test, use require.ErrorIs to check for a specific error type instead of just require.Error. This provides a more precise assertion.

  2. Simplify Voters Field: The Voters field in the expected response can be simplified by using a slice literal instead of a slice of structs. This improves readability and reduces verbosity.

- Voters: []types.VoterList{
-   {
-     VoterAddress: voter,
-     VoteType:     types.VoteType_SuccessObservation,
-   },
- },
+ Voters: []types.VoterList{{voter, types.VoteType_SuccessObservation}},
x/observer/keeper/ballot_test.go (1)

211-310: Suggestions for improvement:

The TestKeeper_ClearMaturedBallots function is well-structured and covers various scenarios. However, consider the following suggestions to enhance the test:

  1. Extract the hardcoded numberOfBallots value as a constant or use a random number to ensure the tests are more robust.
  2. Extract the event counting logic into a separate helper function to avoid duplication in the first and third sub-tests.
  3. Use append instead of initializing the ballots slice with a fixed size based on numberOfBallots to make the code more flexible.
x/emissions/abci_test.go (2)

Line range hint 206-330: Consider refactoring the test for better readability, robustness, and performance.

While the test covers the core functionality well, consider the following improvements:

  1. Split the test into smaller, focused sub-tests using t.Run() for better readability and maintainability. Each sub-test can cover a specific scenario, such as successful distribution, edge cases, and error scenarios.

  2. Add more assertions to cover edge cases and error scenarios, such as:

    • Testing with an empty observer set.
    • Testing with no ballots.
    • Testing with insufficient funds in the emission pool.
    • Testing with invalid parameters.
  3. Optimize the test by reducing the number of blocks (numberOfTestBlocks) to the minimum required to cover the scenarios. This will make the test run faster without compromising the coverage.

  4. Use more concise assertions by leveraging helper functions or libraries like testify/require. This will make the test more readable and maintainable.


Line range hint 332-487: Consider enhancing the test for better robustness and maintainability.

The test is well-structured and covers the important scenarios. The use of table-driven tests is a good practice. However, consider the following improvements:

  1. Add assertions for error scenarios, such as:

    • Testing with an invalid observer set.
    • Testing with invalid ballots.
    • Testing with insufficient funds in the emission pool.
  2. Extract the common setup code into a helper function to avoid duplication and improve readability. The setup code includes:

    • Creating the keeper instances.
    • Setting up the observer set and ballots.
    • Funding the emission pool.
    • Setting the parameters.

This will make the test more maintainable and easier to extend with new scenarios.

Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between a957b0c and 7e771da.

Files ignored due to path filters (6)
  • typescript/zetachain/zetacore/observer/ballot_pb.d.ts is excluded by !**/*_pb.d.ts
  • typescript/zetachain/zetacore/observer/events_pb.d.ts is excluded by !**/*_pb.d.ts
  • typescript/zetachain/zetacore/observer/query_pb.d.ts is excluded by !**/*_pb.d.ts
  • x/observer/types/ballot.pb.go is excluded by !**/*.pb.go, !**/*.pb.go
  • x/observer/types/events.pb.go is excluded by !**/*.pb.go, !**/*.pb.go
  • x/observer/types/query.pb.go is excluded by !**/*.pb.go, !**/*.pb.go
Files selected for processing (16)
  • changelog.md (1 hunks)
  • proto/zetachain/zetacore/observer/ballot.proto (1 hunks)
  • proto/zetachain/zetacore/observer/events.proto (2 hunks)
  • proto/zetachain/zetacore/observer/query.proto (1 hunks)
  • testutil/keeper/mocks/emissions/observer.go (1 hunks)
  • x/emissions/abci.go (3 hunks)
  • x/emissions/abci_test.go (4 hunks)
  • x/emissions/types/expected_keepers.go (1 hunks)
  • x/observer/keeper/ballot.go (3 hunks)
  • x/observer/keeper/ballot_test.go (1 hunks)
  • x/observer/keeper/events.go (1 hunks)
  • x/observer/keeper/events_test.go (1 hunks)
  • x/observer/keeper/grpc_query_ballot.go (1 hunks)
  • x/observer/keeper/grpc_query_ballot_test.go (1 hunks)
  • x/observer/types/ballot.go (1 hunks)
  • x/observer/types/ballot_test.go (1 hunks)
Files skipped from review due to trivial changes (1)
  • changelog.md
Additional context used
Path-based instructions (15)
x/emissions/types/expected_keepers.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

proto/zetachain/zetacore/observer/ballot.proto (1)

Pattern **/*.proto: Review the Protobuf definitions, point out issues relative to compatibility, and expressiveness.

x/observer/keeper/grpc_query_ballot.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

proto/zetachain/zetacore/observer/events.proto (1)

Pattern **/*.proto: Review the Protobuf definitions, point out issues relative to compatibility, and expressiveness.

x/observer/keeper/events.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

x/observer/keeper/events_test.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

testutil/keeper/mocks/emissions/observer.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

x/observer/keeper/ballot.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

x/observer/types/ballot.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

x/observer/keeper/grpc_query_ballot_test.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

x/emissions/abci.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

x/observer/keeper/ballot_test.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

proto/zetachain/zetacore/observer/query.proto (1)

Pattern **/*.proto: Review the Protobuf definitions, point out issues relative to compatibility, and expressiveness.

x/observer/types/ballot_test.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

x/emissions/abci_test.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

Additional comments not posted (19)
proto/zetachain/zetacore/observer/ballot.proto (1)

45-48: LGTM!

The VoterList message is well-structured and follows the protocol buffer conventions. The field names are descriptive and the types are appropriate. The use of the existing VoteType enum for the vote_type field ensures type safety.

This message definition aligns with the PR objectives of tracking voter information and can be effectively used to represent a voter's address and their corresponding vote type.

x/observer/keeper/grpc_query_ballot.go (1)

46-46: Refactoring Approved: Voter List Generation Delegated to a Separate Method

The refactoring of the voter list generation logic into the GenerateVoterList method improves code clarity and maintainability. It encapsulates the complexity of constructing the voter list, reducing the potential for errors in the BallotByIdentifier function.

However, to ensure a comprehensive review, it is recommended to also review the implementation of the GenerateVoterList method to verify its correctness and efficiency.

proto/zetachain/zetacore/observer/events.proto (2)

7-7: LGTM!

The import statement is necessary for using the VoterList message in the EventBallotDeleted message.


19-24: LGTM!

The EventBallotDeleted message is well-defined and captures the necessary information for a ballot deletion event. The use of repeated and (gogoproto.nullable) = false for the voters field is a good practice to ensure data integrity.

x/observer/keeper/events_test.go (1)

77-79: LGTM!

The RemoveQuotes function is simple and straightforward. The code changes are approved.

testutil/keeper/mocks/emissions/observer.go (1)

18-21: LGTM!

The new mock function ClearMaturedBallots is correctly implemented. It properly registers the invocation with the provided arguments using the Called method from the mock.Mock library, which is the expected behavior for a mock function.

x/observer/keeper/ballot.go (5)

23-26: LGTM!

The DeleteBallot function is implemented correctly and follows the standard pattern for deleting data from the store using a prefix store. The code changes are approved.


28-31: LGTM!

The DeleteBallotList function is implemented correctly and follows the standard pattern for deleting data from the store using a prefix store. The code changes are approved.


54-54: LGTM!

The changes to the GetMaturedBallots function improve the clarity and modularity of the code by separating the height calculation logic into a new helper function GetMaturedBallotHeight. The code changes are approved.


79-88: LGTM!

The ClearMaturedBallots function is well-structured and encapsulates the logic for clearing matured ballots effectively. It iterates over the list of ballots, deletes each one using the DeleteBallot method, and emits an event for each deletion. It also deletes the ballot list corresponding to the matured height using the DeleteBallotList method. The code changes are approved.


90-92: LGTM!

The GetMaturedBallotHeight function is a simple and clear implementation of the height calculation logic. It improves the readability and modularity of the code by separating this logic from the GetMaturedBallots function. The code changes are approved.

x/observer/keeper/grpc_query_ballot_test.go (1)

Line range hint 14-80: LGTM!

The TestKeeper_HasVoted function is well-structured and covers important scenarios. The code changes are approved.

x/emissions/abci.go (3)

13-13: LGTM!

The import statement is necessary and correctly added.


106-112: LGTM!

The code changes for initializing the ballots slice and accumulating the ballots are correctly implemented.


167-169: LGTM!

The code changes for clearing the matured ballots are correctly implemented.

x/observer/keeper/ballot_test.go (2)

122-163: LGTM!

The TestKeeper_DeleteBallot function is well-structured and covers the necessary scenarios for testing the deletion of ballots. The use of sub-tests enhances readability and maintainability.


165-209: LGTM!

The TestKeeper_DeleteBallotList function is well-structured and covers the necessary scenarios for testing the deletion of ballot lists. The use of sub-tests enhances readability and maintainability.

proto/zetachain/zetacore/observer/query.proto (1)

252-252: Approve the non-nullable option for the voters field.

The addition of the (gogoproto.nullable) = false option for the voters field enhances data integrity by enforcing that the list cannot contain null values. This change aligns with the goal of improving the robustness of the voters field.

Verify the removal of the VoterList message.

The VoterList message has been removed from the diff. While this change does not directly affect the QueryBallotByIdentifierResponse message, it is important to ensure that the removal of the VoterList message does not introduce any compatibility issues or unintended consequences in other parts of the codebase.

Please confirm that the removal of the VoterList message is intentional and does not impact the functionality or compatibility of the system.

x/observer/types/ballot_test.go (1)

482-585: Excellent test coverage for the GenerateVoterList method.

The TestBallot_GenerateVoterList function is a valuable addition to the test suite. It employs a table-driven approach to test the GenerateVoterList method of the Ballot struct, covering scenarios with success observations, failure observations, and mixed observations.

The test cases are well-defined, and the expected voter lists are clearly specified. This approach enhances the readability and maintainability of the test code.

Great work on improving the test coverage!

x/observer/keeper/events.go Outdated Show resolved Hide resolved
x/observer/keeper/events_test.go Outdated Show resolved Hide resolved
x/observer/keeper/events_test.go Outdated Show resolved Hide resolved
x/observer/types/ballot.go Outdated Show resolved Hide resolved
@kingpinXD kingpinXD changed the title refactor: delete balots after maturity refactor: delete ballots after maturity Sep 11, 2024
Copy link
Contributor

@skosito skosito left a comment

Choose a reason for hiding this comment

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

looks good, just couple minor comments

x/observer/keeper/ballot.go Outdated Show resolved Hide resolved
x/observer/keeper/ballot.go Outdated Show resolved Hide resolved
x/observer/types/ballot.go Show resolved Hide resolved
x/emissions/abci.go Outdated Show resolved Hide resolved
@kingpinXD kingpinXD requested a review from skosito September 16, 2024 17:54
@kingpinXD kingpinXD changed the title refactor: delete ballots after maturity refactor(zetacore): delete ballots after maturity Sep 17, 2024
@kingpinXD kingpinXD requested a review from swift1337 September 23, 2024 04:08

// ClearMaturedBallotsAndBallotList deletes all matured ballots and the list of ballots for a given height.
// It also emits an event for each ballot deleted.
func (k Keeper) ClearMaturedBallotsAndBallotList(ctx sdk.Context, ballots []types.Ballot, maturityBlocks int64) {
Copy link
Member

Choose a reason for hiding this comment

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

I agree with @swift1337 , we should add more encapsulation, the external module shouldn't need to provide a list of ballot

-> You provide an height
-> You can get all ballots from that height in the function
-> You delete all the ballots

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The primary reason for not doing that is that the ballots are already fetched once, and I would want to avoid reading the same data from the store twice.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think you need to reread the store for ballots? The ballot list from height give the ID list that can be directly used in the delete function?

This is small optimization in any case I would consider the encapsulation of the code more important

Copy link
Contributor Author

@kingpinXD kingpinXD Sep 30, 2024

Choose a reason for hiding this comment

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

That is true, but the delete ballot event uses other fields of the ballot.

We could alternatively fire the event from abci.go, but I feel that firing it from the for loop is better.
IMO, the current design looks cleaner.

Fetch ballotslist -> Fetch Ballot -> distribute rewards -> delete them.

The new flow would be
Fetch ballots -> distribute rewards -> Fetch ballotslist ->Fetch Ballots -> delete them.

Copy link
Member

Choose a reason for hiding this comment

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

The current interface doesn't respect encapsulation principle. We delete ballots from a list and a BallotListForHeight value, while the list of ballots can be derived from this height. Both values should be deleted atomically from the same inputs, the current interface allows an external module to create an inconsistent state for the ballot

func (k Keeper) ClearMaturedBallotsAndBallotList(ctx sdk.Context, ballots []types.Ballot, maturityBlocks int64) {
for _, ballot := range ballots {
k.DeleteBallot(ctx, ballot.BallotIdentifier)
EmitEventBallotDeleted(ctx, ballot)
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we need an event here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Once indexed, the event can be used to query details about deleted ballots without having to query an archive node with an older height.
#942 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I do agree though we should remove the event if its not useful .

Copy link
Member

Choose a reason for hiding this comment

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

I agree we should remove it. This will just cause further state size increases right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Events would go into the blockstore , and I think nodes have the option to not store them through configuration, events usually are not part of the application.db .
But yeah, we should avoid adding anything to the node that we don't need
The primary use case that I can think of , where we use the data from these events is for debugging to see if there is a particular observer missing votes consistently fro more than maturityBlocks

x/observer/keeper/ballot.go Outdated Show resolved Hide resolved
x/observer/keeper/ballot.go Show resolved Hide resolved
@kingpinXD kingpinXD requested a review from lumtis September 26, 2024 18:34
@kingpinXD kingpinXD marked this pull request as draft November 5, 2024 23:27
@lumtis
Copy link
Member

lumtis commented Nov 6, 2024

Small note: let's keep this one aside for now to not introduce migration scripts as we already heavy operations with gateway and Solana

@kingpinXD
Copy link
Contributor Author

Hi @lumtis
Should we revisit this for the next release?

We can consider breaking the pr down, into

  • Change in logic
  • Migration script
    And only add the former if in case a long-running migration script is not desired

@lumtis
Copy link
Member

lumtis commented Dec 19, 2024

Hi @lumtis Should we revisit this for the next release?

We can consider breaking the pr down, into

  • Change in logic
  • Migration script
    And only add the former if in case a long-running migration script is not desired

We actually want to remove all old ballot so we can easily query all active ballots

@kingpinXD kingpinXD marked this pull request as ready for review December 20, 2024 18:30
@kingpinXD kingpinXD requested a review from a team as a code owner December 20, 2024 18:30
@kingpinXD kingpinXD requested a review from gartnera December 20, 2024 18:46
func (k Keeper) ClearMaturedBallotsAndBallotList(ctx sdk.Context, ballots []types.Ballot, maturityBlocks int64) {
for _, ballot := range ballots {
k.DeleteBallot(ctx, ballot.BallotIdentifier)
EmitEventBallotDeleted(ctx, ballot)
Copy link
Member

Choose a reason for hiding this comment

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

I agree we should remove it. This will just cause further state size increases right?

x/observer/migrations/v9/migrate.go Outdated Show resolved Hide resolved
x/observer/migrations/v9/migrate.go Show resolved Hide resolved
@@ -30,18 +42,21 @@ func (k Keeper) GetBallot(ctx sdk.Context, index string) (val types.Ballot, foun
return val, true
}

func (k Keeper) GetBallotList(ctx sdk.Context, height int64) (val types.BallotListForHeight, found bool) {
func (k Keeper) GetBallotListForHeight(ctx sdk.Context, height int64) (val types.BallotListForHeight, found bool) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Would just returning a types.BallotListForHeight be enough for the caller?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it should be fine , but this pr just renames the function ,
We can consider changing the signature in a separate PR, as the function is used in a few different places.

if !found {
continue
}
k.DeleteBallot(ctx, ballotIndex)
Copy link
Contributor

Choose a reason for hiding this comment

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

what happens if the ballot is still pending with minority votes (e.g., 4/9)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the chances of that are quite unlikely, that is why we have maturity blocks
However, if that does happen, a new ballot would be created when the fifth vote comes in, and the four observers who already voted would need to revote. This can be triggered by adding trackers manually.

Overall though the maturity blocks should be adjusted so that it has enough time for a ballot to finalize as we do not want to keep the ballots in the system indefinitly

@kingpinXD kingpinXD requested a review from ws4charlie December 20, 2024 19:56
@kingpinXD kingpinXD self-assigned this Dec 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a mechanism to output all incomplete inbound ballots zetacore : Delete Ballots after distribution
7 participants