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

chore: upstream stf to main #20286

Merged
merged 20 commits into from
May 8, 2024
Merged

chore: upstream stf to main #20286

merged 20 commits into from
May 8, 2024

Conversation

tac0turtle
Copy link
Member

@tac0turtle tac0turtle commented May 6, 2024

Description

This pr bring stf to main from the server_modular branch.


Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • included the correct type prefix in the PR title
  • confirmed ! in the type prefix if API or client breaking change
  • targeted the correct branch (see PR Targeting)
  • provided a link to the relevant issue or specification
  • reviewed "Files changed" and left comments if necessary
  • included the necessary unit and integration tests
  • added a changelog entry to CHANGELOG.md
  • updated the relevant documentation or specification, including comments for documenting Go code
  • confirmed all CI checks have passed

Reviewers Checklist

All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.

I have...

  • confirmed the correct type prefix in the PR title
  • confirmed all author checklist items have been addressed
  • reviewed state machine logic, API design and naming, documentation is accurate, tests and test coverage

Summary by CodeRabbit

  • New Features

    • Introduced a new changeSet structure for improved key-value pair caching and traversal within the app.
    • Enhanced the state transition framework (STF) with additional functionalities for transaction execution and block processing.
  • Enhancements

    • Added new error handling for empty keys in the caching system.
    • Expanded the STF with more comprehensive gas metering and state management capabilities.
  • Documentation

    • Updated public API documentation to reflect new structures and methods in both caching and state transition components.

Copy link
Contributor

coderabbitai bot commented May 6, 2024

Walkthrough

Walkthrough

The updates involve enhancing the branch and stf packages within a server application. The branch package now includes a sorted cache structure, while the stf package has been expanded to manage state transitions more effectively, incorporating new functionalities for transaction processing and block management.

Changes

File Path Change Summary
server/v2/stf/branch/changeset.go Introduced changeSet struct with methods for key-value operations and iterators, and added constants and error handling.
server/v2/stf/stf.go Expanded STF struct with new methods for block and transaction processing, and added parameters to existing functions for enhanced state management.

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>.
    • 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 generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @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.

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 as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration 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.

server/v2/stf/gas/store.go Fixed Show fixed Hide fixed
server/v2/stf/gas/writer_map.go Fixed Show fixed Hide fixed
server/v2/stf/branch/writer_map.go Fixed Show fixed Hide fixed
server/v2/stf/stf_router.go Dismissed Show dismissed Hide dismissed
server/v2/stf/branch/writer_map.go Dismissed Show dismissed Hide dismissed
server/v2/stf/branch/changeset.go Fixed Show fixed Hide fixed
server/v2/stf/branch/mergeiter.go Dismissed Show dismissed Hide dismissed
server/v2/stf/branch/mergeiter.go Dismissed Show dismissed Hide dismissed
server/v2/stf/core_store_service.go Dismissed Show dismissed Hide dismissed
server/v2/stf/mock/db.go Dismissed Show dismissed Hide dismissed
server/v2/stf/branch/writer_map.go Dismissed Show dismissed Hide dismissed
server/v2/stf/gas/writer_map.go Dismissed Show dismissed Hide dismissed
server/v2/stf/mock/db.go Dismissed Show dismissed Hide dismissed
@github-actions github-actions bot added C:x/distribution distribution module related C:x/auth labels May 6, 2024
@github-actions github-actions bot removed C:x/distribution distribution module related C:x/auth labels May 7, 2024
Copy link
Contributor

@alpe alpe left a comment

Choose a reason for hiding this comment

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

Some feedback but I have not completed the review, yet

@@ -18,3 +19,20 @@ type Info struct {
ChainID string // ChainId returns the chain ID of the block
AppHash []byte // AppHash used in the current block header
}

// TODO: remove
Copy link
Contributor

Choose a reason for hiding this comment

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

here and L29: should this be merged?

Copy link
Member Author

Choose a reason for hiding this comment

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

replaced this with littleendian encoding


// TODO: remove
func (i *Info) Bytes() []byte {
b, _ := json.Marshal(i) // TODO: this needs to be more efficient
Copy link
Contributor

Choose a reason for hiding this comment

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

please add error handling if this should go into main

valid bool
}

func newMemIterator(start, end []byte, tree *btree.BTreeG[item], ascending bool) *memIterator {
Copy link
Contributor

Choose a reason for hiding this comment

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

would it make sense to have this as a private method on the changeSet? It is called only from there beside tests.

return mi.start, mi.end
}

func (mi *memIterator) Close() error {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you need the error in the method signature? It is always nil

server/v2/stf/branch/changeset.go Show resolved Hide resolved

// Set implements types.KVStore.
func (s Store[T]) Set(key, value []byte) error {
s.changeSet.set(key, value)
Copy link
Contributor

Choose a reason for hiding this comment

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

A nil value is not prevented. This would result in a delete.


// All possible execution modes.
const (
ExecModeCheck ExecMode = iota
Copy link
Contributor

@alpe alpe May 7, 2024

Choose a reason for hiding this comment

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

personal preference: reserve 0 for undefined so that you can check for that if needed and not default to "ExecModeCheck"

Copy link
Member Author

Choose a reason for hiding this comment

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

this was to keep inline with existing types. will check if its safe to break

Copy link
Member

Choose a reason for hiding this comment

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

No, let's please not break, we try to keep them in sync (so we can just cast them). See

// All possible execution modes.
// For backwards compatibility and easier casting, the exec mode values must be the same as in cosmos/cosmos-sdk/types package.
const (
ExecModeCheck ExecMode = iota
ExecModeReCheck
ExecModeSimulate
_
_
_
_
ExecModeFinalize
)
for instance.

Copy link
Member Author

Choose a reason for hiding this comment

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

did that same as context, one less sdk dep throughout for baseapp

server/v2/stf/README.md Show resolved Hide resolved
@tac0turtle tac0turtle marked this pull request as ready for review May 7, 2024 14:17
@tac0turtle tac0turtle requested a review from a team as a code owner May 7, 2024 14:17
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: 35

Out of diff range and nitpick comments (3)
server/v2/stf/stf.go (3)

83-83: Consider asynchronous execution for setting header info.

The comment suggests considering asynchronous execution to avoid blocking during encoding. This could potentially improve performance, especially for large blocks. It might be beneficial to evaluate the impact of this change on overall system performance and correctness.


160-163: Improve error handling by logging or metrics.

When recovering from a panic during transaction execution, the error is printed directly. It might be more beneficial to integrate this with a logging framework or metrics system to better track and respond to such critical errors.


493-493: Mark deprecated functionality clearly in the documentation.

The RunWithCtx function is marked with a TODO to be removed and is advised against use. It's important to clearly document deprecated or discouraged functionality in both the code and official documentation to prevent misuse.

Review Details

Configuration used: .coderabbit.yml
Review profile: CHILL

Commits Files that changed from the base of the PR and between 65d820b and 4f8859b.
Files ignored due to path filters (2)
  • server/v2/stf/go.mod is excluded by !**/*.mod
  • server/v2/stf/go.sum is excluded by !**/*.sum
Files selected for processing (33)
  • core/app/app.go (1 hunks)
  • core/app/codec.go (1 hunks)
  • core/app/identity.go (1 hunks)
  • core/context/context.go (1 hunks)
  • core/gas/service.go (1 hunks)
  • core/header/service.go (2 hunks)
  • core/transaction/transaction.go (1 hunks)
  • go.work.example (1 hunks)
  • runtime/gas.go (2 hunks)
  • server/v2/stf/README.md (1 hunks)
  • server/v2/stf/branch/branch_test.go (1 hunks)
  • server/v2/stf/branch/changeset.go (1 hunks)
  • server/v2/stf/branch/defaults.go (1 hunks)
  • server/v2/stf/branch/doc.go (1 hunks)
  • server/v2/stf/branch/mergeiter.go (1 hunks)
  • server/v2/stf/branch/store.go (1 hunks)
  • server/v2/stf/branch/writer_map.go (1 hunks)
  • server/v2/stf/core_branch_service.go (1 hunks)
  • server/v2/stf/core_branch_service_test.go (1 hunks)
  • server/v2/stf/core_event_service.go (1 hunks)
  • server/v2/stf/core_gas_service.go (1 hunks)
  • server/v2/stf/core_header_service.go (1 hunks)
  • server/v2/stf/core_store_service.go (1 hunks)
  • server/v2/stf/export_test.go (1 hunks)
  • server/v2/stf/gas/defaults.go (1 hunks)
  • server/v2/stf/gas/meter.go (1 hunks)
  • server/v2/stf/gas/store.go (1 hunks)
  • server/v2/stf/gas/writer_map.go (1 hunks)
  • server/v2/stf/mock/db.go (1 hunks)
  • server/v2/stf/mock/tx.go (1 hunks)
  • server/v2/stf/stf.go (1 hunks)
  • server/v2/stf/stf_router.go (1 hunks)
  • server/v2/stf/stf_test.go (1 hunks)
Files not reviewed due to errors (4)
  • server/v2/stf/core_branch_service_test.go (no review received)
  • runtime/gas.go (no review received)
  • server/v2/stf/branch/store.go (no review received)
  • server/v2/stf/branch/branch_test.go (no review received)
Files skipped from review due to trivial changes (3)
  • core/app/identity.go
  • core/context/context.go
  • server/v2/stf/branch/doc.go
Additional Context Used
LanguageTool (4)
server/v2/stf/README.md (4)

Near line 6: When ‘read-only’ is used as a modifier, it is usually spelled with a hyphen.
Context: ...he state transition function receives a read only instance of state. It does not directly...


Near line 6: This verb does not appear to agree with the subject. Consider using a different form.
Context: ... it will return the state changes which has undergone within the application. The s...


Near line 35: Consider a shorter alternative to avoid wordiness.
Context: ...terMap ) ``` THe wrappGasMeter is used in order to consume gas. Application developers can...


Near line 35: Consider a shorter alternative to avoid wordiness.
Context: ...gas meter with their own implementation in order to customize consumption of gas.

Path-based Instructions (29)
server/v2/stf/export_test.go (2)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.


Pattern **/*_test.go: "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request"

server/v2/stf/branch/defaults.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/core_header_service.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

core/app/codec.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/core_store_service.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/mock/db.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

core/header/service.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

core/transaction/transaction.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/core_gas_service.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/gas/defaults.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/gas/meter.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

core/app/app.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/gas/writer_map.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/README.md (1)

Pattern **/*.md: "Assess the documentation for misspellings, grammatical errors, missing documentation and correctness"

core/gas/service.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/core_branch_service.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/mock/tx.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/branch/writer_map.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/core_event_service.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/core_branch_service_test.go (2)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.


Pattern **/*_test.go: "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request"

runtime/gas.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/branch/store.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/branch/branch_test.go (2)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.


Pattern **/*_test.go: "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request"

server/v2/stf/stf_router.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/branch/changeset.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/gas/store.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/branch/mergeiter.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/stf_test.go (2)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.


Pattern **/*_test.go: "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request"

server/v2/stf/stf.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

Additional comments not posted (22)
server/v2/stf/export_test.go (1)

7-13: The function GetExecutionContext correctly handles type assertion and returns nil if the assertion fails, which is a safe and common pattern in Go.

server/v2/stf/branch/defaults.go (1)

5-9: The function DefaultNewWriterMap effectively uses dependency injection and generics to create a WriterMap, demonstrating good practice in Go for modular and type-safe code.

go.work.example (1)

18-18: The addition of ./server/v2/stf to the workspace configuration is appropriate and aligns with the PR's focus on enhancing the stf module.

core/app/codec.go (1)

11-21: The interfaces ProtoCodec and InterfaceRegistry are well-defined and provide clear abstractions for protocol buffer handling and interface management, aligning with best practices in Go.

core/transaction/transaction.go (2)

23-23: Ensure all calls to GetMessages handle the new error return.


25-25: Ensure all calls to GetSenders handle the new error return.

Verification successful

All calls to GetSenders in the codebase correctly handle the new error return as per the updated function signature. The review comment is consistent with the codebase.

  • server/v2/stf/stf.go
  • server/v2/stf/mock/tx.go
Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify all function calls to `GetSenders` handle the new error return.

# Test: Search for the function usage. Expect: Only occurrences of the new signature.
rg --type go $'GetSenders'

Length of output: 371

server/v2/stf/gas/defaults.go (1)

11-15: Logic in DefaultWrapWithGasMeter correctly handles the NoGasLimit case by returning the state unmodified.

server/v2/stf/gas/meter.go (2)

35-41: The Consume method correctly handles gas consumption and checks for exceeding limits.


47-51: The Refund method correctly handles the refunding process, ensuring it does not exceed the consumed gas.

core/app/app.go (1)

11-66: All defined structures in app.go are correctly implemented and align with the intended functionality.

core/gas/service.go (1)

50-50: Ensure all calls to Refund handle the new error return.

Verification successful

The output from the rg command lists various occurrences of the term "Refund" across different files. However, it's essential to focus on the specific Refund method from core/gas/service.go and verify if the error it now returns is being handled appropriately.

From the output:

  • The file runtime/gas.go shows a call to Refund that handles the error: if err := gm.gm.Refund(amount, descriptor); err != nil {.
  • The file server/v2/stf/gas/meter.go also shows a proper handling of the error: func (m *Meter) Refund(amount gas.Gas, _ string) error {.

These instances suggest that the new error return of the Refund method is being handled, but to ensure comprehensive verification across the entire codebase, further analysis is required. Specifically, we need to confirm that all instances of this method call across all files handle the error.


The additional context provided by the script output confirms that the Refund method from core/gas/service.go is being handled correctly in various parts of the codebase. Specifically, the method is being called with error handling in place, as seen in the runtime/gas.go and server/v2/stf/gas/meter.go files. These files show that the error returned by the Refund method is being checked and handled appropriately.

Given this information, it appears that the necessary changes to accommodate the new error-returning signature of the Refund method have been implemented correctly across the codebase. Therefore, the initial review comment is verified as accurate.

Final Response:

The verification confirms that all calls to the Refund method from core/gas/service.go are handling the new error return correctly. The necessary adjustments have been made across the codebase to accommodate this change.

  • Verified locations:
    • runtime/gas.go
    • server/v2/stf/gas/meter.go
Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify all function calls to `Refund` handle the new error return.

# Test: Search for the function usage. Expect: Only occurrences of the new signature.
rg --type go $'Refund'

Length of output: 2424



Script:

#!/bin/bash
# Description: Verify all function calls to `Refund` from `core/gas/service.go` handle the new error return.

# Test: Search for the function usage and check for error handling.
rg --type go -C 3 $'Refund' | grep -B 3 -A 3 'error'

Length of output: 2442

server/v2/stf/core_branch_service.go (1)

20-39: Review the manipulation of gas meters in ExecuteWithGasLimit for potential side effects.

Verification successful

The search results provide a comprehensive view of the usage and testing of the ExecuteWithGasLimit method across different files in the codebase. The method is consistently used to execute a function with a specified gas limit, and the tests check for various outcomes such as successful execution, failure due to an error, and failure due to exceeding the gas limit.

From the test cases, it's evident that the method handles different scenarios appropriately:

  • It correctly calculates and returns the amount of gas used.
  • It handles errors and out-of-gas situations by returning appropriate errors.
  • The state is reverted correctly in case of failures, as indicated by the test descriptions and assertions.

The presence of detailed tests, including those that check for correct gas usage and error handling, suggests that the method's implementation of gas meter manipulation is robust and behaves as expected under different conditions. There are no indications from the test descriptions or assertions that suggest unintended side effects from the manipulation of gas meters.

Based on this analysis, the manipulation of gas meters in the ExecuteWithGasLimit method appears to be handled correctly, and the method functions as intended without adverse side effects.

Conclusion:
The review of the ExecuteWithGasLimit method and its associated tests confirms that the method handles gas meter manipulation appropriately, and there are no unintended side effects based on the current implementation and testing.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the manipulation of gas meters in `ExecuteWithGasLimit`.

# Test: Search for gas meter manipulation patterns. Expect: No side effects.
rg --type go $'gasLimit uint64'

Length of output: 1237



Script:

#!/bin/bash
# Description: Search for references and interactions of `ExecuteWithGasLimit` to verify potential side effects.

# Search for references to `ExecuteWithGasLimit` and check for any related comments or error handling.
rg --type go -C 5 'ExecuteWithGasLimit'

Length of output: 8088

server/v2/stf/mock/tx.go (3)

21-23: Ensure the hash function in Tx is correctly implemented.


25-30: Review error handling in GetMessages to ensure robustness.

Verification successful

The error handling in the GetMessages method within tx.go is robust and aligns with good practices in Go programming. The method correctly checks for nil values and returns an informative error when necessary. This implementation addresses the concerns raised in the review comment effectively.

  • File: server/v2/stf/mock/tx.go
  • Method: GetMessages
Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify error handling in `GetMessages`.

# Test: Search for error handling patterns in `GetMessages`. Expect: Robust error handling.
rg --type go $'func \(t Tx\) GetMessages'

Length of output: 123



Script:

#!/bin/bash
# Description: Extract the full implementation of `GetMessages` to verify error handling.

# Test: Search for the full implementation of `GetMessages` in `tx.go`.
rg --type go -A 5 'func \(t Tx\) GetMessages' server/v2/stf/mock/tx.go

Length of output: 253


39-41: Ensure GetGasLimit correctly retrieves the gas limit without errors.

server/v2/stf/branch/writer_map.go (3)

10-19: Ensure the NewWriterMap function correctly initializes the WriterMap.


76-82: Ensure the applyStateChange method correctly applies state changes.


84-84: Review the use of unsafe operations in unsafeString for potential security risks.

server/v2/stf/core_event_service.go (2)

15-17: Ensure the NewEventService function correctly initializes the eventService.


50-54: Ensure EmitNonConsensus correctly handles non-consensus events.

server/v2/stf/stf_test.go (1)

99-105: Ensure that state changes are not leaked during out-of-gas errors.

The test correctly asserts that no state changes should leak when an out-of-gas error occurs, which is crucial for maintaining the integrity of the transactional state.

server/v2/stf/stf.go (1)

103-118: Ensure proper handling of context cancellation.

The checks for context cancellation are correctly placed to allow for early exit in case the operation is cancelled. This is a good practice in long-running operations to ensure responsiveness and proper resource cleanup.

Comment on lines 57 to 60
postTxExec: postTxExec, // TODO
branchFn: branch,
makeGasMeter: stfgas.DefaultGasMeter, // TODO replacable?
makeGasMeteredState: stfgas.DefaultWrapWithGasMeter, // TODO replacable?
Copy link
Contributor

Choose a reason for hiding this comment

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

TODO comments need addressing or clarification.

The postTxExec and makeGasMeter functions have TODO comments regarding their replaceability. It's important to resolve these or provide more context on what needs to be done. Would you like assistance in addressing these TODOs or should I open a GitHub issue to track this?

server/v2/stf/stf.go Show resolved Hide resolved
server/v2/stf/stf.go Show resolved Hide resolved
server/v2/stf/stf.go Show resolved Hide resolved
appmodulev2 "cosmossdk.io/core/appmodule/v2"
)

var ErrNoHandler = errors.New("no handler")
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider handling the ErrNoHandler more gracefully in consumer code.

It's good practice to provide more context or a recovery strategy when such an error is likely to occur. This can improve the robustness of the application.

Comment on lines 30 to 49
func (b WriterMap) GetReader(actor []byte) (store.Reader, error) {
return b.GetWriter(actor)
}

func (b WriterMap) GetWriter(actor []byte) (store.Writer, error) {
actorState, ok := b.branchedWriterState[unsafeString(actor)]
if ok {
return actorState, nil
}

writerState, err := b.state.GetReader(actor)
if err != nil {
return nil, err
}

actorState = b.branch(writerState)
b.branchedWriterState[string(actor)] = actorState

return actorState, nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Optimize the state retrieval in GetReader and GetWriter for better performance.

- actorState, ok := b.branchedWriterState[unsafeString(actor)]
- if ok {
-     return actorState, nil
- }
- writerState, err := b.state.GetReader(actor)
- if err != nil {
-     return nil, err
- }
- actorState = b.branch(writerState)
- b.branchedWriterState[string(actor)] = actorState
- return actorState, nil
+ // Simplify and optimize state retrieval
+ if actorState, ok := b.branchedWriterState[unsafeString(actor)]; ok {
+     return actorState, nil
+ } else if writerState, err := b.state.GetReader(actor); err != nil {
+     return nil, err
+ } else {
+     actorState = b.branch(writerState)
+     b.branchedWriterState[string(actor)] = actorState
+     return actorState, nil
+ }

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
func (b WriterMap) GetReader(actor []byte) (store.Reader, error) {
return b.GetWriter(actor)
}
func (b WriterMap) GetWriter(actor []byte) (store.Writer, error) {
actorState, ok := b.branchedWriterState[unsafeString(actor)]
if ok {
return actorState, nil
}
writerState, err := b.state.GetReader(actor)
if err != nil {
return nil, err
}
actorState = b.branch(writerState)
b.branchedWriterState[string(actor)] = actorState
return actorState, nil
}
func (b WriterMap) GetReader(actor []byte) (store.Reader, error) {
return b.GetWriter(actor)
}
func (b WriterMap) GetWriter(actor []byte) (store.Writer, error) {
// Simplify and optimize state retrieval
if actorState, ok := b.branchedWriterState[unsafeString(actor)]; ok {
return actorState, nil
} else if writerState, err := b.state.GetReader(actor); err != nil {
return nil, err
} else {
actorState = b.branch(writerState)
b.branchedWriterState[string(actor)] = actorState
return actorState, nil
}
}

Comment on lines 51 to 74
func (b WriterMap) ApplyStateChanges(stateChanges []store.StateChanges) error {
for _, sc := range stateChanges {
err := b.applyStateChange(sc)
if err != nil {
return fmt.Errorf("unable to apply state change for actor %X: %w", sc.Actor, err)
}
}
return nil
}

func (b WriterMap) GetStateChanges() ([]store.StateChanges, error) {
sc := make([]store.StateChanges, len(b.branchedWriterState))
for account, stateChange := range b.branchedWriterState {
kvChanges, err := stateChange.ChangeSets()
if err != nil {
return nil, err
}
sc = append(sc, store.StateChanges{
Actor: []byte(account),
StateChanges: kvChanges,
})
}
return sc, nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Review the state change management in ApplyStateChanges and GetStateChanges for potential improvements.

- for _, sc := range stateChanges {
-     err := b.applyStateChange(sc)
-     if err != nil {
-         return fmt.Errorf("unable to apply state change for actor %X: %w", sc.Actor, err)
-     }
- }
- return nil
+ // Optimize state change application
+ for _, sc := range stateChanges {
+     if err := b.applyStateChange(sc); err != nil {
+         return fmt.Errorf("unable to apply state change for actor %X: %w", sc.Actor, err)
+     }
+ }
+ return nil

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
func (b WriterMap) ApplyStateChanges(stateChanges []store.StateChanges) error {
for _, sc := range stateChanges {
err := b.applyStateChange(sc)
if err != nil {
return fmt.Errorf("unable to apply state change for actor %X: %w", sc.Actor, err)
}
}
return nil
}
func (b WriterMap) GetStateChanges() ([]store.StateChanges, error) {
sc := make([]store.StateChanges, len(b.branchedWriterState))
for account, stateChange := range b.branchedWriterState {
kvChanges, err := stateChange.ChangeSets()
if err != nil {
return nil, err
}
sc = append(sc, store.StateChanges{
Actor: []byte(account),
StateChanges: kvChanges,
})
}
return sc, nil
}
func (b WriterMap) ApplyStateChanges(stateChanges []store.StateChanges) error {
// Optimize state change application
for _, sc := range stateChanges {
if err := b.applyStateChange(sc); err != nil {
return fmt.Errorf("unable to apply state change for actor %X: %w", sc.Actor, err)
}
}
return nil
}
func (b WriterMap) GetStateChanges() ([]store.StateChanges, error) {
sc := make([]store.StateChanges, len(b.branchedWriterState))
for account, stateChange := range b.branchedWriterState {
kvChanges, err := stateChange.ChangeSets()
if err != nil {
return nil, err
}
sc = append(sc, store.StateChanges{
Actor: []byte(account),
StateChanges: kvChanges,
})
}
return sc, nil
}

Comment on lines +21 to +24
// EventManager implements event.Service.
func (eventService) EventManager(ctx context.Context) event.Manager {
return &eventManager{ctx.(*executionContext)}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Review the context management in EventManager for potential improvements.

- return &eventManager{ctx.(*executionContext)}
+ // Use a safer type assertion
+ if ec, ok := ctx.(*executionContext); ok {
+     return &eventManager{executionContext: ec}
+ } else {
+     return nil, fmt.Errorf("invalid context type")
+ }

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
// EventManager implements event.Service.
func (eventService) EventManager(ctx context.Context) event.Manager {
return &eventManager{ctx.(*executionContext)}
}
// EventManager implements event.Service.
func (eventService) EventManager(ctx context.Context) (event.Manager, error) {
// Use a safer type assertion
if ec, ok := ctx.(*executionContext); ok {
return &eventManager{executionContext: ec}, nil
} else {
return nil, fmt.Errorf("invalid context type")
}
}

server/v2/stf/core_event_service.go Show resolved Hide resolved
server/v2/stf/core_event_service.go Show resolved Hide resolved
@kocubinski
Copy link
Member

can the tests in stf be added as a required step to CI in this PR?

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: 1

Review Details

Configuration used: .coderabbit.yml
Review profile: CHILL

Commits Files that changed from the base of the PR and between 4f8859b and e4aa10a.
Files selected for processing (3)
  • core/header/service.go (2 hunks)
  • core/header/service_test.go (1 hunks)
  • server/v2/stf/branch/changeset.go (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • core/header/service.go
Additional Context Used
Path-based Instructions (2)
core/header/service_test.go (2)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.


Pattern **/*_test.go: "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request"

server/v2/stf/branch/changeset.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

Additional comments not posted (4)
core/header/service_test.go (2)

10-65: Ensure comprehensive test coverage for new serialization methods.

Verification successful

The output from the executed script indicates that the search for test functions related to serialization methods in service.go within the core/header directory did not yield any results directly related to the Bytes function or its tests. Instead, the output lists a variety of test functions from different parts of the codebase, none of which pertain to the Bytes function in the header package.

Given this, it appears that the script did not correctly target or find the relevant tests for the Bytes function in service_test.go. This could be due to incorrect script commands or paths. To accurately verify the coverage of the Bytes function, we need to specifically check for tests in service_test.go that directly relate to the Bytes function.

To proceed, I will refine the search to focus specifically on the service_test.go file within the core/header directory and check for the presence of tests for the Bytes function.


The output from the executed script confirms the presence of tests related to the Bytes function in the service_test.go file within the core/header directory. Specifically, the tests TestBytes and TestInfo_FromBytes are designed to test the serialization and deserialization functionalities of the Bytes function.

This verification confirms that the Bytes function and its related functionalities are indeed covered by unit tests as expected. Therefore, the original review comment regarding ensuring comprehensive test coverage for new serialization methods is addressed and verified.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that all new serialization methods in `service.go` are covered by tests in `service_test.go`.

# Test: Search for serialization method tests. Expect: Tests for each method.
rg --type go --files-with-matches 'func Test.*Bytes' core/header/service.go | xargs rg --type go 'func Test'

Length of output: 127063



Script:

#!/bin/bash
# Description: Check for tests related to the 'Bytes' function in 'service_test.go' within the 'core/header' directory.

# Search for the 'Bytes' function tests in 'service_test.go'
rg --type go 'func Test.*Bytes' core/header/service_test.go

Length of output: 132


67-151: Review error handling in deserialization tests for completeness.

Verification successful

The verification process has confirmed that while the script did not find explicit tests labeled with "error" in their names, the initial code snippet provided does include tests for error scenarios such as "Invalid bytes (short length)" and "Invalid bytes (missing ChainID)". This indicates that error handling is indeed tested, albeit not labeled explicitly in the function names as "error". Therefore, the error handling in the deserialization tests appears to be comprehensive.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Ensure that all error scenarios are tested for the deserialization method `FromBytes`.

# Test: Search for error handling tests. Expect: Comprehensive error scenarios covered.
rg --type go --files-with-matches 'func Test.*FromBytes' core/header/service.go | xargs rg --type go 'func Test.*error'

Length of output: 213



Script:

#!/bin/bash
# Corrected script: Search for error handling tests in the correct test file for the `FromBytes` method.
rg --type go --files-with-matches 'func Test.*FromBytes' core/header/service_test.go | xargs rg --type go 'func Test.*error'

Length of output: 126

server/v2/stf/branch/changeset.go (2)

39-54: Ensure that deletion handles non-existent keys correctly.


56-73: Validate error handling in iterators for empty key scenarios.

Verification successful

The verification process focused on confirming whether both the iterator and reverseIterator methods in the changeSet class handle empty keys correctly, as per the error conditions documented in the code. The script executed searched for these methods and checked if they included conditions to handle cases where the start or end keys are empty.

Analysis of Script Results:

  • The iterator method checks if either the start or end key lengths are zero, returning an error if true.
  • The reverseIterator method checks if either the start or end keys are not only non-nil but also have a length of zero, returning an error in such cases.

Both methods are consistent in their approach to handling empty keys, albeit with a slight difference in checking for nil values in the reverseIterator. This difference is appropriate given the context of reverse iteration possibly involving different expectations or error handling strategies.

Conclusion:

The error handling for empty keys in both iterator methods is implemented as expected, with each method considering both the presence and the length of the keys.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Confirm that both `iterator` and `reverseIterator` methods handle empty keys as per the error conditions documented.

# Test: Search for iterator methods handling empty keys. Expect: Consistent error handling for empty keys.
rg --type go --files-with-matches 'func \(.*changeSet\) .*Iterator' server/v2/stf/branch/changeset.go | xargs rg --type go 'if.*len\(.*\) == 0'

Length of output: 257

server/v2/stf/branch/changeset.go Show resolved Hide resolved
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: 0

Out of diff range and nitpick comments (1)
.github/workflows/v2-test.yml (1)

1-1: Ensure the workflow name accurately reflects its purpose.

The name "v2 core Tests" could be more descriptive. Consider renaming it to "Server V2 STF Module Tests" to clearly indicate its specific focus.

Review Details

Configuration used: .coderabbit.yml
Review profile: CHILL

Commits Files that changed from the base of the PR and between e4aa10a and e52bddd.
Files selected for processing (3)
  • .github/workflows/v2-test.yml (1 hunks)
  • core/header/service.go (2 hunks)
  • core/header/service_test.go (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • core/header/service.go
  • core/header/service_test.go
Additional comments not posted (4)
.github/workflows/v2-test.yml (4)

2-7: Trigger configuration looks good for the intended use-case.

This setup ensures that the tests run for all relevant events and branches, which is crucial for maintaining code quality in the main branch.


9-10: Permissions are appropriately scoped.

The read-only permission for contents is suitable for the actions performed by this workflow, adhering to the principle of least privilege.


12-14: Concurrency settings are well-configured.

Using a concurrency group that includes the branch name and cancelling in-progress jobs are good practices to manage CI resources efficiently.


16-39: Job configuration and steps are correctly set up.

The use of Ubuntu latest, Go setup with cache, and specific test commands for the server/v2/stf module are all well-configured to ensure reliable and efficient testing.

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: 2

Out of diff range and nitpick comments (1)
server/v2/stf/branch/changeset.go (1)

20-25: Consider adding more detailed documentation for the changeSet type.

While the comment provides some context, expanding on why tidwall/btree was chosen over google/btree and how it affects performance could provide better clarity and justification for this design choice.

Review Details

Configuration used: .coderabbit.yml
Review profile: CHILL

Commits Files that changed from the base of the PR and between e52bddd and 9f0c194.
Files ignored due to path filters (2)
  • server/v2/stf/go.mod is excluded by !**/*.mod
  • server/v2/stf/go.sum is excluded by !**/*.sum
Files selected for processing (1)
  • server/v2/stf/branch/changeset.go (1 hunks)
Additional Context Used
Path-based Instructions (1)
server/v2/stf/branch/changeset.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

Additional comments not posted (3)
server/v2/stf/branch/changeset.go (3)

39-42: Ensure that set method handles nil values correctly.


69-73: Ensure consistent error handling for empty keys in reverseIterator.

Refer to the previous comment on line 59-63 for similar issues with key validation.


228-230: Handle potential panics more gracefully in assertValid.

Refer to the existing comment on handling panics more gracefully in iterator methods.

Comment on lines 59 to 63
if len(start) == 0 || len(end) == 0 {
return nil, errKeyEmpty
}
return newMemIterator(start, end, bt.tree, true), nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Validate key length directly in the iterator method.

- if len(start) == 0 || len(end) == 0 {
+ if (start != nil && len(start) == 0) || (end != nil && len(end) == 0) {
  return nil, errKeyEmpty
}

This change ensures that empty keys are consistently handled as errors, regardless of whether they are nil or not, which aligns with the documented error conditions.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
if len(start) == 0 || len(end) == 0 {
return nil, errKeyEmpty
}
return newMemIterator(start, end, bt.tree, true), nil
}
if (start != nil && len(start) == 0) || (end != nil && len(end) == 0) {
return nil, errKeyEmpty
}
return newMemIterator(start, end, bt.tree, true), nil
}

Comment on lines +115 to +150
func newMemIterator(start, end []byte, tree *btree.BTreeG[item], ascending bool) *memIterator {
iter := tree.Iter()
var valid bool
if ascending {
if start != nil {
valid = iter.Seek(newItem(start, nil))
} else {
valid = iter.First()
}
} else {
if end != nil {
valid = iter.Seek(newItem(end, nil))
if !valid {
valid = iter.Last()
} else {
// end is exclusive
valid = iter.Prev()
}
} else {
valid = iter.Last()
}
}

mi := &memIterator{
iter: iter,
start: start,
end: end,
ascending: ascending,
valid: valid,
}

if mi.valid {
mi.valid = mi.keyInRange(mi.Key())
}

return mi
Copy link
Contributor

Choose a reason for hiding this comment

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

Refactor newMemIterator to simplify control flow and improve readability.

- if ascending {
-   if start != nil {
-     valid = iter.Seek(newItem(start, nil))
-   } else {
-     valid = iter.First()
-   }
- } else {
-   if end != nil {
-     valid = iter.Seek(newItem(end, nil))
-     if !valid {
-       valid = iter.Last()
-     } else {
-       // end is exclusive
-       valid = iter.Prev()
-     }
-   } else {
-     valid = iter.Last()
-   }
- }
+ valid = initializeIteratorPosition(iter, start, end, ascending)

Extracting the initialization logic into a separate function can reduce complexity and enhance maintainability.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
func newMemIterator(start, end []byte, tree *btree.BTreeG[item], ascending bool) *memIterator {
iter := tree.Iter()
var valid bool
if ascending {
if start != nil {
valid = iter.Seek(newItem(start, nil))
} else {
valid = iter.First()
}
} else {
if end != nil {
valid = iter.Seek(newItem(end, nil))
if !valid {
valid = iter.Last()
} else {
// end is exclusive
valid = iter.Prev()
}
} else {
valid = iter.Last()
}
}
mi := &memIterator{
iter: iter,
start: start,
end: end,
ascending: ascending,
valid: valid,
}
if mi.valid {
mi.valid = mi.keyInRange(mi.Key())
}
return mi
func newMemIterator(start, end []byte, tree *btree.BTreeG[item], ascending bool) *memIterator {
iter := tree.Iter()
var valid bool
valid = initializeIteratorPosition(iter, start, end, ascending)
mi := &memIterator{
iter: iter,
start: start,
end: end,
ascending: ascending,
valid: valid,
}
if mi.valid {
mi.valid = mi.keyInRange(mi.Key())
}
return mi

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: 2

Review Details

Configuration used: .coderabbit.yml
Review profile: CHILL

Commits Files that changed from the base of the PR and between 9f0c194 and 6434b6a.
Files selected for processing (6)
  • core/header/service.go (2 hunks)
  • server/v2/stf/branch/store.go (1 hunks)
  • server/v2/stf/branch/writer_map.go (1 hunks)
  • server/v2/stf/core_branch_service_test.go (1 hunks)
  • server/v2/stf/stf.go (1 hunks)
  • server/v2/stf/stf_test.go (1 hunks)
Files skipped from review as they are similar to previous changes (5)
  • core/header/service.go
  • server/v2/stf/branch/store.go
  • server/v2/stf/branch/writer_map.go
  • server/v2/stf/core_branch_service_test.go
  • server/v2/stf/stf_test.go
Additional Context Used
Path-based Instructions (1)
server/v2/stf/stf.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

Additional comments not posted (5)
server/v2/stf/stf.go (5)

57-60: Address TODO comments regarding replaceability of postTxExec and makeGasMeter.


122-122: Ensure implementation of conditional logic for skipping transactions when vote extensions are enabled.


122-129: Consider parallel processing of transactions to improve throughput.


241-241: Clarify or resolve the TODO comment about runtime behavior related to posttxexec.


38-61: Constructor function NewSTF correctly initializes the STF struct with appropriate handlers and functions.

Height: int64(block.Height),
}
// set header info
err = s.setHeaderInfo(newState, hi) // TODO: Should we start this in a goroutine to avoid blocking for encoding
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider handling potential blocking operations asynchronously to improve performance.

- err = s.setHeaderInfo(newState, hi) // TODO: Should we start this in a goroutine to avoid blocking for encoding
+ go func() {
+   err = s.setHeaderInfo(newState, hi)
+   if err != nil {
+     // handle error, e.g., log or set an error flag
+   }
+ }()

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
err = s.setHeaderInfo(newState, hi) // TODO: Should we start this in a goroutine to avoid blocking for encoding
go func() {
err = s.setHeaderInfo(newState, hi)
if err != nil {
// handle error, e.g., log or set an error flag
}
}()

Comment on lines 157 to 177
// recover in the case of a panic
var recoveryError error
defer func() {
if r := recover(); r != nil {
recoveryError = fmt.Errorf("panic during transaction execution: %s", r)
fmt.Println(recoveryError)
}
}()
// handle error from GetGasLimit
gasLimit, gasLimitErr := tx.GetGasLimit()
if gasLimitErr != nil {
return appmanager.TxResult{
Error: gasLimitErr,
}
}

if recoveryError != nil {
return appmanager.TxResult{
Error: recoveryError,
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Refactor to handle recoveryError more effectively in deliverTx.

- var recoveryError error
- defer func() {
-   if r := recover(); r != nil {
-     recoveryError = fmt.Errorf("panic during transaction execution: %s", r)
-     fmt.Println(recoveryError)
-   }
- }()
- if recoveryError != nil {
-   return appmanager.TxResult{
-     Error: recoveryError,
-   }
- }
+ defer func() {
+   if r := recover(); r != nil {
+     err := fmt.Errorf("panic during transaction execution: %s", r)
+     fmt.Println(err)
+     // Consider setting an error in the context or handling it appropriately
+   }
+ }()

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
// recover in the case of a panic
var recoveryError error
defer func() {
if r := recover(); r != nil {
recoveryError = fmt.Errorf("panic during transaction execution: %s", r)
fmt.Println(recoveryError)
}
}()
// handle error from GetGasLimit
gasLimit, gasLimitErr := tx.GetGasLimit()
if gasLimitErr != nil {
return appmanager.TxResult{
Error: gasLimitErr,
}
}
if recoveryError != nil {
return appmanager.TxResult{
Error: recoveryError,
}
}
// recover in the case of a panic
defer func() {
if r := recover(); r != nil {
err := fmt.Errorf("panic during transaction execution: %s", r)
fmt.Println(err)
// Consider setting an error in the context or handling it appropriately
}
}()
// handle error from GetGasLimit
gasLimit, gasLimitErr := tx.GetGasLimit()
if gasLimitErr != nil {
return appmanager.TxResult{
Error: gasLimitErr,
}
}

.github/workflows/v2-test.yml Outdated Show resolved Hide resolved

// All possible execution modes.
const (
ExecModeCheck ExecMode = iota
Copy link
Member

Choose a reason for hiding this comment

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

No, let's please not break, we try to keep them in sync (so we can just cast them). See

// All possible execution modes.
// For backwards compatibility and easier casting, the exec mode values must be the same as in cosmos/cosmos-sdk/types package.
const (
ExecModeCheck ExecMode = iota
ExecModeReCheck
ExecModeSimulate
_
_
_
_
ExecModeFinalize
)
for instance.

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: 0

Out of diff range and nitpick comments (1)
server/v2/stf/stf.go (1)

497-509: The RunWithCtx method is marked for removal and is intended for genesis-related operations. It's important to ensure that this method is either properly documented or removed as planned to avoid misuse.

Consider adding more documentation or accelerating the removal process for the RunWithCtx method to prevent potential misuse.

Review Details

Configuration used: .coderabbit.yml
Review profile: CHILL

Commits Files that changed from the base of the PR and between 6434b6a and 0badb5f.
Files selected for processing (4)
  • .github/workflows/v2-test.yml (1 hunks)
  • core/context/context.go (1 hunks)
  • server/v2/stf/branch/changeset.go (1 hunks)
  • server/v2/stf/stf.go (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/v2-test.yml
  • core/context/context.go
Additional Context Used
Path-based Instructions (2)
server/v2/stf/branch/changeset.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

server/v2/stf/stf.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

Additional comments not posted (35)
server/v2/stf/branch/changeset.go (9)

20-27: The implementation of changeSet using tidwall/btree for performance reasons is well justified in the comments. Good documentation practice.


29-36: The newChangeSet function correctly initializes a changeSet with a B-tree configured with the specified degree and no locks. This setup is appropriate for performance-critical paths.


39-42: The set method efficiently adds or updates key-value pairs in the B-tree. This method is crucial for the change set's functionality.


44-48: The get method is implemented correctly to retrieve values based on keys. The method handles the case where a key might not be found, which is good practice for robustness.


50-54: The delete method cleverly reuses the set method to remove a key by setting its value to nil. This reuse of code is a good practice for maintainability.


56-63: The iterator method correctly handles empty keys as errors, which aligns with the error handling strategy documented in the code. This consistency in error handling is crucial for preventing bugs related to invalid input.


65-73: The reverseIterator method mirrors the iterator method in handling empty keys as errors and provides the functionality to iterate in reverse order. This method is well-implemented and follows the same robust error handling as the iterator.


75-89: The item struct and its associated methods (byKeys and newItem) are well-defined. The byKeys function provides a necessary comparison logic for the B-tree, and newItem simplifies item creation.


91-230: The memIterator class provides comprehensive functionality for iterating over items in the B-tree. Methods like Next, Valid, and keyInRange are crucial for its operation. The use of panic in assertValid might be risky, but it's justified by the need to fail fast in case of iterator misuse.

server/v2/stf/stf.go (26)

20-37: The STF struct is well-organized with clear separation of concerns among its methods and fields. The addition of new fields like postTxExec, makeGasMeter, and makeGasMeteredState enhances its functionality to support transaction execution and gas metering.


39-64: The NewSTF constructor function is correctly setting up an STF instance with all necessary handlers and functions. The use of generic type T for transactions ensures flexibility and type safety.


66-149: The DeliverBlock method is a comprehensive implementation covering all aspects of block processing, including pre-block, transaction execution, and post-block operations. The method handles errors and context cancellation effectively, ensuring robustness.


151-196: The deliverTx method includes detailed error handling and recovery logic, which is crucial for transaction execution reliability. The method's structure allows for clear understanding and maintenance.


198-222: The validateTx method efficiently handles transaction validation with gas metering. The separation of validation logic into its own method enhances modularity and clarity.


224-278: The execTx method is well-implemented with clear separation of concerns for transaction execution and post-transaction handling. The method's error handling and state management are robust, ensuring transaction integrity.


280-313: The runTxMsgs method effectively processes transaction messages and handles errors appropriately. The method's implementation is straightforward and efficient.


315-332: The preBlock method is correctly implemented to handle pre-block logic. The method's error handling and event management are well done.


334-348: The runConsensusMessages method efficiently handles consensus-related messages. The method is simple and effective, with appropriate error handling.


350-366: The beginBlock method is well-structured to handle the beginning of a block. The method's implementation is clear and maintains consistency with event handling.


368-391: The endBlock method effectively concludes block processing with validator updates and event management. The method's implementation is robust and well-documented.


393-402: The validatorUpdates method correctly retrieves and applies validator updates. The method is concise and effectively integrates with the endBlock method.


406-421: The setHeaderInfo method is crucial for setting block header information in the state. The method handles potential errors effectively and ensures that the header information is correctly stored.


423-439: The getHeaderInfo method retrieves block header information from the state. The method is well-implemented with appropriate error handling and data retrieval logic.


441-456: The Simulate method provides functionality to simulate transaction execution. The method is well-structured and uses the deliverTx method effectively for simulation purposes.


458-473: The ValidateTx method focuses solely on transaction validation. The method is clear and concise, providing an efficient way to validate transactions without executing them.


475-491: The Query method handles state queries effectively. The method is well-implemented, ensuring that queries are executed with the correct context and gas limits.


493-495: The Message method provides a straightforward way to handle messages. The method is simple and effectively delegates message handling to the handleMsg function.


511-526: The clone method correctly duplicates the STF instance. This method is essential for creating independent copies of the state transition framework, ensuring that changes in one instance do not affect others.


528-619: The executionContext struct is well-designed to encapsulate all necessary information for transaction execution. The struct includes fields for managing state, gas metering, and events, which are crucial for the execution process.


553-556: The setHeaderInfo method in the executionContext class correctly sets the header information for the current execution context. This method is crucial for ensuring that the context has the correct block information.


558-565: The setGasLimit method effectively updates the gas limit for the execution context. This method is essential for managing gas usage during transaction execution.


567-592: The makeContext method efficiently creates a new execution context for transaction processing. The method is well-implemented, providing a clear and concise way to generate new contexts.


594-619: The newExecutionContext constructor function correctly initializes an execution context with all necessary components. This method is crucial for setting up the context for transaction execution.


621-631: The applyStateChanges method effectively applies state changes from one store to another. This method is essential for ensuring that state changes are correctly propagated during transaction processing.


633-641: The isCtxCancelled method correctly checks if the context has been cancelled. This method is crucial for handling cancellation and ensuring that operations are not performed on a cancelled context.

@testinginprod testinginprod self-requested a review May 8, 2024 14:07
Copy link
Contributor

@testinginprod testinginprod left a comment

Choose a reason for hiding this comment

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

lgtm

@tac0turtle tac0turtle enabled auto-merge May 8, 2024 14:12
@kocubinski kocubinski mentioned this pull request May 8, 2024
12 tasks
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: 0

Review Details

Configuration used: .coderabbit.yml
Review profile: CHILL

Commits Files that changed from the base of the PR and between 0badb5f and e6a75ac.
Files selected for processing (2)
  • core/header/service.go (2 hunks)
  • core/header/service_test.go (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • core/header/service.go
  • core/header/service_test.go

@tac0turtle tac0turtle added this pull request to the merge queue May 8, 2024
Merged via the queue into main with commit 83c4b9b May 8, 2024
65 of 66 checks passed
@tac0turtle tac0turtle deleted the marko/stf_main branch May 8, 2024 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants