-
Notifications
You must be signed in to change notification settings - Fork 4
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
feat: ibc testing framework #73
Conversation
WalkthroughThis update introduces significant enhancements to the IBC (Inter-Blockchain Communication) framework within the application, primarily focusing on a modular approach to middleware handling, improved testing utilities, and clearer semantic definitions. Key changes include the integration of a new token module, refactoring of middleware setup, and the addition of mock components for testing various scenarios, ultimately promoting code clarity, extensibility, and maintainability. Changes
Sequence Diagram(s)sequenceDiagram
participant App as Application
participant Token as Token Module
participant Middleware as IBC Middleware
participant TestUtil as Testing Utilities
App->>Middleware: Initialize with Token Module
Middleware->>Token: Setup Token Transfer Logic
Token->>Middleware: Confirm Token Setup
Middleware->>App: Middleware Ready
App->>TestUtil: Configure Testing Utilities
TestUtil->>App: Testing Environment Set Up
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? TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Additionally, you can add CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 15
Outside diff range, codebase verification and nitpick comments (30)
testutil/ibc/types/expected_keepers.go (2)
1-2
: Add file-level documentation.Consider adding a file-level comment to describe the purpose of this file.
// Package types defines interfaces and types used in the IBC testing package. package types
8-9
: Fix the comment formatting.The comment should be on a single line to follow Go documentation conventions.
// StakingKeeper defines the expected staking keeper interface used in the IBC testing package.
testutil/ibc/mock/privval.go (1)
16-18
: Clarify the purpose of thePV
struct.The comment should emphasize that this struct is for testing purposes only.
- // MockPV implements PrivValidator without any safety or persistence. + // PV implements PrivValidator without any safety or persistence. + // This is a mock implementation for testing purposes only.testutil/ibc/config.go (3)
17-22
: Ensure default values are defined and documented.The struct is well-defined, but the default values for the fields should be documented.
// TendermintConfig provides configuration for Tendermint clients. type TendermintConfig struct { TrustLevel ibctm.Fraction // Default: DefaultTrustLevel TrustingPeriod time.Duration // Default: TrustingPeriod UnbondingPeriod time.Duration // Default: UnbondingPeriod MaxClockDrift time.Duration // Default: MaxClockDrift }
37-40
: Ensure default values are defined and documented.The struct is well-defined, but the default values for the fields should be documented.
// ConnectionConfig provides configuration for IBC connections. type ConnectionConfig struct { DelayPeriod uint64 // Default: DefaultDelayPeriod Version *connectiontypes.Version // Default: ConnectionVersion }
49-53
: Ensure default values are defined and documented.The struct is well-defined, but the default values for the fields should be documented.
// ChannelConfig provides configuration for IBC channels. type ChannelConfig struct { PortID string // Default: mock.PortID Version string // Default: DefaultChannelVersion Order channeltypes.Order // Default: channeltypes.UNORDERED }x/token/setup_test.go (1)
32-47
: Remove nolint directive and handle type assertion error.The
nolint:errcheck
directive suppresses the error check for the type assertion ofApp
to*app.LorenzoApp
. Given thatApp
is an interface, the type assertion could fail ifApp
holds a different implementation. It is important to handle this potential error properly instead of suppressing it.
- Remove the
nolint:errcheck
directive.- Implement error handling for the type assertion of
App
to*app.LorenzoApp
.Analysis chain
Setup logic looks good. Verify nolint directive.
The setup logic is comprehensive and ensures that the test environment is correctly initialized.
However, verify if the nolint directive for errcheck is necessary.
Verify the necessity of nolint directive for errcheck.
The
nolint:errcheck
directive is used in multiple places in the codebase, suggesting a pattern of intentionally ignoring error checks for specific cases. To determine if this is necessary forsuite.chainA
andsuite.chainB
assignments, we need to investigate theApp
field ofLorenzoChainA
andLorenzoChainB
and theLorenzoApp
type to understand if the type assertion can fail or produce an error.
Verify the necessity of nolint directive for errcheck.
The
nolint:errcheck
directive is used to suppress error checking for the type assertion ofApp
to*app.LorenzoApp
. To determine if this suppression is justified, we need to verify if theApp
field inibctesting.TestChain
is always of type*app.LorenzoApp
or if there are scenarios where it could be of a different type.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify if the nolint directive for errcheck is necessary. # Test: Search for errcheck directives. Expect: Only necessary directives. rg --type go 'nolint:errcheck'Length of output: 2862
Script:
#!/bin/bash # Description: Investigate the App field and LorenzoApp type to understand the necessity of nolint:errcheck directive. # Find the definition of LorenzoChainA and LorenzoChainB to understand the App field. rg --type go 'LorenzoChainA' -A 5 # Find the definition of LorenzoApp to understand its type and behavior. rg --type go 'type LorenzoApp' -A 10Length of output: 6861
Script:
#!/bin/bash # Description: Verify the type of the App field in ibctesting.TestChain to understand if nolint:errcheck directive is necessary. # Find the definition of TestChain to understand the type of the App field. rg --type go 'type TestChain' -A 10 # Find where the App field is set in TestChain instances to verify its type. rg --type go 'App' -A 5Length of output: 197078
x/plan/keeper/keeper_test.go (1)
Potential Issue with Setup Function
The TODO comment in
x/token/keeper/setup_test.go
suggests that the setup with the genesis merge function might require re-evaluation. This is relevant to the setup logic inx/plan/keeper/keeper_test.go
as it uses a similar setup function. Please review theapp.SetupWithGenesisMergeFn
function to ensure it is error-free and reliable.
x/token/keeper/setup_test.go
: "TODO: setup with genesis merge fn need recheck, it's probably not errorless."Analysis chain
Line range hint
73-103
:
Setup logic looks good. Verify TODO comment.The setup logic is comprehensive and ensures that the test environment is correctly initialized.
However, verify the TODO comment about the setup function.
Verify the TODO comment in
x/token/keeper/setup_test.go
.The TODO comment in
x/token/keeper/setup_test.go
suggests that the setup with the genesis merge function might require re-evaluation. This is relevant to the setup logic inx/plan/keeper/keeper_test.go
as it uses a similar setup function.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the TODO comment about the setup function. # Test: Search for TODO comments. Expect: Only necessary TODO comments. rg --type go 'TODO:'Length of output: 996
Script:
#!/bin/bash # Description: Review the TODO comment in `x/token/keeper/setup_test.go` to understand its context. # Search for the TODO comment in `x/token/keeper/setup_test.go` and display surrounding lines for context. rg --type go --context 10 'TODO: setup with genesis merge fn need recheck' x/token/keeper/setup_test.goLength of output: 943
testutil/ibc/events.go (6)
19-30
: Ensure comprehensive error handling forParseClientIDFromEvents
.The function correctly parses the client ID from events but does not provide specific error messages for different failure scenarios. Consider enhancing error messages for better debugging.
- return "", fmt.Errorf("client identifier event attribute not found") + return "", fmt.Errorf("client identifier event attribute not found in events: %v", events)
34-46
: Ensure comprehensive error handling forParseConnectionIDFromEvents
.The function correctly parses the connection ID from events but does not provide specific error messages for different failure scenarios. Consider enhancing error messages for better debugging.
- return "", fmt.Errorf("connection identifier event attribute not found") + return "", fmt.Errorf("connection identifier event attribute not found in events: %v", events)
50-61
: Ensure comprehensive error handling forParseChannelIDFromEvents
.The function correctly parses the channel ID from events but does not provide specific error messages for different failure scenarios. Consider enhancing error messages for better debugging.
- return "", fmt.Errorf("channel identifier event attribute not found") + return "", fmt.Errorf("channel identifier event attribute not found in events: %v", events)
65-119
: Ensure comprehensive error handling forParsePacketFromEvents
.The function correctly parses the packet from events but does not provide specific error messages for different failure scenarios. Consider enhancing error messages for better debugging.
- return channeltypes.Packet{}, fmt.Errorf("acknowledgement event attribute not found") + return channeltypes.Packet{}, fmt.Errorf("acknowledgement event attribute not found in events: %v", events)
123-134
: Ensure comprehensive error handling forParseAckFromEvents
.The function correctly parses the acknowledgement from events but does not provide specific error messages for different failure scenarios. Consider enhancing error messages for better debugging.
- return nil, fmt.Errorf("acknowledgement event attribute not found") + return nil, fmt.Errorf("acknowledgement event attribute not found in events: %v", events)
136-164
: EnsureAssertEvents
function handles missing events gracefully.The function asserts that expected events are present in the actual events but does not provide specific error messages for different failure scenarios. Consider enhancing error messages for better debugging.
- suite.Require().True(hasEvent, "event: %s was not found in events", eventName) + suite.Require().True(hasEvent, "event: %s was not found in events: %v", eventName, actual)x/token/ibc_middleware_test.go (2)
15-16
: Clarify the note.The note in the comment is unclear. Consider rephrasing for better clarity.
- // Note: mock packet received instead sending an actual packet. + // Note: a mock packet is used instead of sending an actual packet.
109-110
: Clarify the note.The note in the comment is unclear. Consider rephrasing for better clarity.
- // Note: mock packet timeout instead sending an actual packet. + // Note: a mock packet timeout is used instead of sending an actual packet.testutil/ibc/mock/ibc_module.go (13)
46-46
: Add function documentation.Consider adding a detailed comment to describe the purpose and functionality of the
OnChanOpenInit
function.
69-69
: Add function documentation.Consider adding a detailed comment to describe the purpose and functionality of the
OnChanOpenTry
function.
88-88
: Add function documentation.Consider adding a detailed comment to describe the purpose and functionality of the
OnChanOpenAck
function.
97-97
: Add function documentation.Consider adding a detailed comment to describe the purpose and functionality of the
OnChanOpenConfirm
function.
106-106
: Add function documentation.Consider adding a detailed comment to describe the purpose and functionality of the
OnChanCloseInit
function.
115-115
: Add function documentation.Consider adding a detailed comment to describe the purpose and functionality of the
OnChanCloseConfirm
function.
124-124
: Add function documentation.Consider adding a detailed comment to describe the purpose and functionality of the
OnRecvPacket
function.
149-149
: Add function documentation.Consider adding a detailed comment to describe the purpose and functionality of the
OnAcknowledgementPacket
function.
167-167
: Add function documentation.Consider adding a detailed comment to describe the purpose and functionality of the
OnTimeoutPacket
function.
185-185
: Add function documentation.Consider adding a detailed comment to describe the purpose and functionality of the
UnmarshalPacketData
function.
194-194
: Add function documentation.Consider adding a detailed comment to describe the purpose and functionality of the
GetMockRecvCanaryCapabilityName
function.
199-199
: Add function documentation.Consider adding a detailed comment to describe the purpose and functionality of the
GetMockAckCanaryCapabilityName
function.
204-204
: Add function documentation.Consider adding a detailed comment to describe the purpose and functionality of the
GetMockTimeoutCanaryCapabilityName
function.testutil/ibc/solomachine.go (1)
36-47
: Consider adding comments for each field in theSolomachine
struct.Adding comments will improve code readability and maintainability.
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files ignored due to path filters (2)
x/token/types/genesis.pb.go
is excluded by!**/*.pb.go
x/token/types/token.pb.go
is excluded by!**/*.pb.go
Files selected for processing (57)
- app/app.go (3 hunks)
- app/test_helper.go (9 hunks)
- proto/lorenzo/token/v1/genesis.proto (1 hunks)
- proto/lorenzo/token/v1/token.proto (2 hunks)
- testutil/ibc/LICENSE (1 hunks)
- testutil/ibc/README.md (1 hunks)
- testutil/ibc/app.go (1 hunks)
- testutil/ibc/chain.go (1 hunks)
- testutil/ibc/config.go (1 hunks)
- testutil/ibc/coordinator.go (1 hunks)
- testutil/ibc/endpoint.go (1 hunks)
- testutil/ibc/events.go (1 hunks)
- testutil/ibc/mock/ack.go (1 hunks)
- testutil/ibc/mock/doc.go (1 hunks)
- testutil/ibc/mock/events.go (1 hunks)
- testutil/ibc/mock/ibc_app.go (1 hunks)
- testutil/ibc/mock/ibc_module.go (1 hunks)
- testutil/ibc/mock/ibc_module_test.go (1 hunks)
- testutil/ibc/mock/mock.go (1 hunks)
- testutil/ibc/mock/privval.go (1 hunks)
- testutil/ibc/mock/privval_test.go (1 hunks)
- testutil/ibc/path.go (1 hunks)
- testutil/ibc/solomachine.go (1 hunks)
- testutil/ibc/types/expected_keepers.go (1 hunks)
- testutil/ibc/utils.go (1 hunks)
- testutil/ibc/values.go (1 hunks)
- x/agent/keeper/keeper_test.go (3 hunks)
- x/agent/keeper/msg_server_test.go (4 hunks)
- x/fee/keeper/keeper_test.go (2 hunks)
- x/ibctransfer/ibc_module.go (1 hunks)
- x/ibctransfer/keeper/msg_server_test.go (2 hunks)
- x/ibctransfer/keeper/setup_test.go (2 hunks)
- x/plan/keeper/keeper_test.go (3 hunks)
- x/token/client/cli/tx.go (2 hunks)
- x/token/ibc_middleware.go (3 hunks)
- x/token/ibc_middleware_test.go (1 hunks)
- x/token/keeper/convert.go (5 hunks)
- x/token/keeper/evm_hooks.go (2 hunks)
- x/token/keeper/evm_hooks_test.go (1 hunks)
- x/token/keeper/genesis_test.go (2 hunks)
- x/token/keeper/grpc_query.go (1 hunks)
- x/token/keeper/grpc_query_test.go (1 hunks)
- x/token/keeper/ibc_callbacks.go (5 hunks)
- x/token/keeper/keeper.go (1 hunks)
- x/token/keeper/msg_server_test.go (8 hunks)
- x/token/keeper/params.go (1 hunks)
- x/token/keeper/register.go (1 hunks)
- x/token/keeper/setup_test.go (4 hunks)
- x/token/keeper/token_pair.go (1 hunks)
- x/token/keeper/token_pair_test.go (1 hunks)
- x/token/keeper/utils_test.go (1 hunks)
- x/token/module.go (3 hunks)
- x/token/setup_test.go (1 hunks)
- x/token/types/errors.go (1 hunks)
- x/token/types/events.go (1 hunks)
- x/token/types/expected_keeper.go (1 hunks)
- x/token/types/msg_test.go (3 hunks)
Files not processed due to max files limit (2)
- x/token/types/params.go
- x/token/types/token_pair.go
Files skipped from review due to trivial changes (14)
- proto/lorenzo/token/v1/genesis.proto
- testutil/ibc/LICENSE
- testutil/ibc/mock/ack.go
- testutil/ibc/mock/doc.go
- x/agent/keeper/msg_server_test.go
- x/ibctransfer/keeper/msg_server_test.go
- x/token/client/cli/tx.go
- x/token/keeper/grpc_query.go
- x/token/keeper/keeper.go
- x/token/keeper/token_pair.go
- x/token/keeper/token_pair_test.go
- x/token/keeper/utils_test.go
- x/token/module.go
- x/token/types/expected_keeper.go
Additional context used
Markdownlint
testutil/ibc/README.md
3-3: Expected: 0 or 2; Actual: 1
Trailing spaces(MD009, no-trailing-spaces)
3-3: Expected: 120; Actual: 129
Line length(MD013, line-length)
5-5: Expected: 120; Actual: 153
Line length(MD013, line-length)
7-7: Expected: 120; Actual: 145
Line length(MD013, line-length)
7-7: null
Files should end with a single newline character(MD047, single-trailing-newline)
Additional comments not posted (130)
testutil/ibc/types/expected_keepers.go (1)
10-12
: LGTM!The interface definition looks good.
x/token/types/events.go (1)
Line range hint
1-12
:
LGTM!The remaining constants are correctly defined. Ensure that the removal of the event type constants does not affect other parts of the codebase.
Verification successful
Verification Successful: The removed event type constants are not used elsewhere in the codebase.
- The constants
EventTypeTokenLock
,EventTypeTokenUnlock
,EventTypeMint
, andEventTypeBurn
were not found in the original file or anywhere else in the codebase.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that the removed event type constants are not used elsewhere in the codebase. # Test: Search for the removed constants. Expect: No occurrences of the removed constants. rg --type go 'EventTypeTokenLock|EventTypeTokenUnlock|EventTypeMint|EventTypeBurn'Length of output: 84
Script:
#!/bin/bash # Description: Verify that the removed event type constants are not used elsewhere in the codebase. # Step 1: Verify the search pattern by checking the constants in the original file. echo "Checking the original file for the presence of the constants:" rg 'EventTypeTokenLock|EventTypeTokenUnlock|EventTypeMint|EventTypeBurn' x/token/types/events.go # Step 2: Re-check the entire codebase for any possible occurrences of these constants. echo "Re-checking the entire codebase for the presence of the constants:" rg --type go 'EventTypeTokenLock|EventTypeTokenUnlock|EventTypeMint|EventTypeBurn'Length of output: 459
x/ibctransfer/ibc_module.go (1)
18-22
: LGTM! But verify the function usage in the codebase.The change to return a pointer to
IBCModule
improves memory efficiency.However, ensure that all function calls to
NewIBCModule
handle the pointer correctly.testutil/ibc/utils.go (1)
13-22
: LGTM! Ensure comprehensive test coverage.The function
ApplyValSetChanges
is implemented correctly and follows best practices for error handling and immutability.Ensure that comprehensive tests are written to cover various scenarios.
proto/lorenzo/token/v1/token.proto (2)
9-19
: LGTM! Improved semantic clarity.The changes to the enum
Source
improve semantic clarity and align with the new context.
31-32
: LGTM! Improved semantic clarity.The changes to the field
source
in the messageTokenPair
improve semantic clarity and align with the new context.x/token/keeper/params.go (4)
Line range hint
8-12
:
LGTM!The
SetParams
method correctly stores the parameters in the key-value store.
Line range hint
13-21
:
LGTM!The
GetParams
method correctly retrieves the parameters from the key-value store.
Line range hint
32-35
:
LGTM!The
IsEVMHookEnabled
method correctly checks if the EVM hook is enabled.
30-30
: Verify the parameter name change.The method now checks
EnableConversion
instead ofEnableConvert
. Ensure that this change is consistent across the codebase.Verification successful
Verification successful: Parameter name change is consistent.
The parameter
EnableConversion
is consistently used across the codebase, confirming the update fromEnableConvert
toEnableConversion
.
x/token/types/genesis.pb.go
x/token/types/params.go
x/token/types/msg_test.go
x/token/keeper/params.go
x/token/keeper/msg_server_test.go
x/token/keeper/evm_hooks.go
x/token/keeper/grpc_query_test.go
x/ibctransfer/keeper/msg_server_test.go
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the usage of the parameter `EnableConversion`. # Test: Search for the parameter usage. Expect: Only occurances of the new parameter name. rg --type go 'EnableConversion'Length of output: 1690
testutil/ibc/mock/ibc_module_test.go (1)
13-32
: LGTM!The
TestCreateCapabilityName
function correctly tests the creation of capability names for different packet scenarios using therequire
package for assertions.testutil/ibc/mock/privval_test.go (3)
15-20
: LGTM!The
TestGetPubKey
function correctly tests the retrieval of the public key from the private validator using therequire
package for assertions.
22-33
: LGTM!The
TestSignVote
function correctly tests the signing of votes by the private validator using therequire
package for assertions.
35-46
: LGTM!The
TestSignProposal
function correctly tests the signing of proposals by the private validator using therequire
package for assertions.x/fee/keeper/keeper_test.go (2)
32-32
: LGTM! But verify the setup process.The code changes are approved.
However, ensure that the
app.Setup
function correctly initializes all required components for the test suite.Verification successful
The setup process in
app.Setup
correctly initializes all required components for the test suite.
- The
Setup
function inapp/test_helper.go
initializes validators, genesis accounts, and the chain state.- It ensures that the necessary components are in place for the tests to run correctly.
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the initialization process in the `app.Setup` function. # Test: Search for the `Setup` function in the `app` package and verify its implementation. Expect: Correct initialization of components. rg --type go -A 20 $'func Setup' | rg 'app'Length of output: 6384
6-6
: Verify the new import statement.Ensure that the
app
package provides all the necessary functionalities previously offered byhelpers
.Verification successful
Verify the completeness of the new import statement.
Ensure that the
app
package covers all functionalities previously provided by thehelpers
package.
The new import statement is verified.
The
app
package provides comprehensive functionalities, including setup and utility functions necessary for the test suite.
Setup
functions and other utility functions are present in theapp
package.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that the `app` package provides all necessary functionalities. # Test: Search for the `Setup` function in the `app` package. Expect: Function definition in the `app` package. rg --type go -A 5 $'func Setup' | rg 'app'Length of output: 2375
Script:
#!/bin/bash # Description: Verify that the `app` package provides all necessary functionalities previously offered by `helpers`. # Search for functions in the `helpers` package. rg --type go -A 5 'func ' | rg 'helpers' # Search for equivalent functions in the `app` package. rg --type go -A 5 'func ' | rg 'app'Length of output: 35149
x/token/types/errors.go (1)
17-20
: Verify the consistency of renumbered error codes.Ensure that the renumbered error codes are consistently reflected throughout the codebase.
testutil/ibc/mock/events.go (4)
17-20
: LGTM!The function correctly returns a mock receive packet event.
22-25
: LGTM!The function correctly returns a mock acknowledgement packet event.
27-30
: LGTM!The function correctly returns a mock timeout packet event.
32-39
: LGTM!The function correctly returns a mock event with the given event type.
testutil/ibc/mock/privval.go (4)
20-22
: LGTM!The constructor function correctly initializes a new
PV
instance with a generated private key.
24-27
: LGTM!The function correctly converts the private key to a Tendermint public key interface.
29-37
: LGTM!The function correctly signs the vote and assigns the signature to the vote.
40-48
: LGTM!The function correctly signs the proposal and assigns the signature to the proposal.
testutil/ibc/config.go (4)
24-31
: LGTM!The constructor function correctly initializes a new
TendermintConfig
instance with default values.
33-35
: LGTM!The function correctly returns the Tendermint client type.
42-46
: LGTM!The constructor function correctly initializes a new
ConnectionConfig
instance with default values.
55-60
: LGTM!The constructor function correctly initializes a new
ChannelConfig
instance with default values.x/token/keeper/genesis_test.go (2)
20-23
: Verify the change fromOwnership
toSource
.Ensure that the change from
Ownership
toSource
in theTokenPair
struct aligns with the new semantics and does not affect the test logic.
66-69
: Verify the change fromOwnership
toSource
.Ensure that the change from
Ownership
toSource
in theTokenPair
struct aligns with the new semantics and does not affect the test logic.x/agent/keeper/keeper_test.go (3)
7-7
: Import change approved.The import of the
app
package is necessary for the updated test setup.
21-21
: Centralized test address creation approved.Using
app.CreateTestAddrs
centralizes the test address creation within the application context, improving consistency.
57-57
: Application-level test setup approved.Using
app.SetupWithGenesisMergeFn
promotes consistency and maintainability in the test environment setup.x/token/keeper/grpc_query_test.go (1)
18-18
: Parameter renaming approved.The assertion update to use
EnableConversion
instead ofEnableConvert
reflects a renaming of the parameter for clarity or consistency.testutil/ibc/values.go (3)
5-18
: Package declaration and imports approved.The package declaration as
ibc
and the included imports are appropriate for the context of the file.
20-44
: Constants approved.The constants are well-defined and appropriate for their intended use in the testing package.
46-66
: Variables approved.The variables are well-defined and appropriate for their intended use in the testing package.
testutil/ibc/mock/ibc_app.go (2)
12-88
: LGTM! Ensure correct usage of callbacks.The
IBCApp
struct definition looks good. Verify that all callback functions are correctly defined and used within the codebase.
90-95
: LGTM!The
NewIBCApp
function correctly initializes and returns a newIBCApp
instance.x/token/ibc_middleware.go (5)
26-29
: LGTM! Ensure correct initialization and usage of pointers.The
IBCMiddleware
struct definition looks good. Verify that the pointers toIBCModule
andkeeper.Keeper
are correctly initialized and used within the codebase.
18-24
: LGTM!The
NewIBCMiddleware
function correctly initializes and returns a newIBCMiddleware
instance.
Line range hint
32-44
:
LGTM! Ensure correct post-processing logic.The
OnRecvPacket
function looks good. Verify that the post-processing logic using the keeper is correctly implemented.
Line range hint
46-64
:
LGTM! Ensure correct post-processing logic.The
OnAcknowledgementPacket
function looks good. Verify that the post-processing logic using the keeper is correctly implemented.
Line range hint
65-82
:
LGTM! Ensure correct post-processing logic.The
OnTimeoutPacket
function looks good. Verify that the post-processing logic using the keeper is correctly implemented.testutil/ibc/path.go (4)
10-14
: LGTM! Ensure correct initialization and usage of endpoints.The
Path
struct definition looks good. Verify that the endpoints are correctly initialized and used within the codebase.
16-30
: LGTM!The
NewPath
function correctly initializes and returns a newPath
instance with default endpoints.
32-36
: LGTM!The
SetChannelOrdered
function correctly sets the channel order for both endpoints to ORDERED.
38-91
: LGTM! Ensure correct packet relay logic.The
RelayPacket
function looks good. Verify that the packet relay logic is correctly implemented and tested.x/token/setup_test.go (5)
1-16
: Imports and struct declaration look good.The imports and struct declaration are appropriate for the test suite.
49-51
: Test suite runner function looks good.The function is standard for running testify suites.
53-64
: Mock transfer packet function looks good.The function correctly initializes the packet with the necessary fields.
67-75
: IBC denom creation function looks good.The function correctly formats the denom trace. The note about multiple hop denom is acknowledged.
77-83
: Mock acknowledgement function looks good.The function correctly handles both success and error cases.
x/token/keeper/setup_test.go (5)
Line range hint
1-22
:
Imports and struct declaration look good.The imports and struct declaration are appropriate for the test suite.
Line range hint
26-30
:
Test suite runner function looks good.The function is standard for running testify suites.
Line range hint
32-34
:
Setup function looks good.The function correctly delegates the setup logic to
execSetupTest
.
Line range hint
93-108
:
Utility functions look good.The functions correctly handle block commits and context updates.
Line range hint
36-70
:
Setup logic looks good. Verify TODO comment.The setup logic is comprehensive and ensures that the test environment is correctly initialized.
However, verify the TODO comment about the setup function.
x/plan/keeper/keeper_test.go (4)
Line range hint
1-31
:
Imports and struct declaration look good.The imports and struct declaration are appropriate for the test suite.
33-33
: Variable initialization looks good.The variable initialization is appropriate and aligns with the consolidation of setup functions.
Line range hint
39-43
:
Test suite runner function looks good.The function is standard for running testify suites.
Line range hint
105-120
:
Utility functions look good.The functions correctly handle block commits and context updates.
x/token/keeper/evm_hooks.go (2)
39-39
: LGTM! The condition check update enhances clarity.The change from
params.EnableConvert
toparams.EnableConversion
is more descriptive and improves code readability.
109-112
: LGTM! The switch-case update refines the logic.The change from
pair.Ownership
topair.Source
and the caseOWNER_EXTERNAL
toOWNER_CONTRACT
enhances the semantic clarity of the code.x/token/keeper/ibc_callbacks.go (2)
37-42
: LGTM! The token pair validation enhances robustness.The new logic to check for the existence of a token pair before proceeding with further operations ensures that only valid token pairs are processed, preventing potential errors related to unregistered tokens.
98-104
: LGTM! The token pair validation enhances robustness.The new logic to check for the existence of a token pair before proceeding with further operations ensures that only valid token pairs are processed, preventing potential errors related to unregistered tokens.
x/ibctransfer/keeper/setup_test.go (2)
70-70
: LGTM! The consolidation of functionality enhances maintainability.The update from
helpers.SetupWithGenesisMergeFn
toapp.SetupWithGenesisMergeFn
reduces dependencies on thehelpers
package and potentially enhances maintainability.
72-72
: LGTM! The reference update aligns with the consolidation of functionality.The update from
helpers.SimAppChainID
toapp.SimAppChainID
aligns with the consolidation of functionality within theapp
package.x/token/keeper/register.go (1)
67-67
: Verify the impact of changing ownership type toOWNER_CONTRACT
.The change in ownership type from
OWNER_EXTERNAL
toOWNER_CONTRACT
affects how token pairs are managed and interacted with. Ensure that this change aligns with the overall design and does not introduce any unintended side effects.x/token/keeper/evm_hooks_test.go (1)
177-177
: Verify the impact of changing the assignment fromOwnership
toSource
.The change in assignment from
Ownership
toSource
suggests a potential redefinition of the role of theSource
attribute. Ensure that this change aligns with the overall design and does not introduce any unintended side effects.testutil/ibc/mock/mock.go (5)
1-21
: LGTM!The package declaration and imports are appropriate for the functionality provided in the file.
23-44
: LGTM!The constants and variables are well-defined and appropriate for the mock module.
48-90
: LGTM!The
PortKeeper
interface andAppModuleBasic
struct definitions, along with their methods, are appropriate and correctly implemented.
92-143
: LGTM!The
AppModule
struct and its methods are well-defined and correctly implemented, adhering to the expected interfaces.
145-158
: LGTM!The
KeyPath
struct and its methods are correctly implemented, adhering to the expected interface.testutil/ibc/coordinator.go (6)
1-11
: LGTM!The package declaration and imports are appropriate for the functionality provided in the file.
13-19
: LGTM!The constants and variables are well-defined and appropriate for the
Coordinator
struct.
21-45
: LGTM!The
Coordinator
struct and its constructor are well-defined and correctly implemented.
47-73
: LGTM!The methods for time management are well-defined and correctly implemented.
75-166
: LGTM!The setup methods are well-defined and correctly implemented.
168-198
: LGTM!The helper methods are well-defined and correctly implemented.
testutil/ibc/app.go (4)
1-40
: LGTM!The package declaration and imports are appropriate for the functionality provided in the file.
44-60
: LGTM!The
TestingApp
interface is well-defined and correctly implemented.
62-85
: LGTM!The
SetupTestingApp
function is well-defined and correctly implemented.
87-195
: LGTM!The
SetupWithGenesisValSet
andSetupWithGenesisValSetAndConsensusParams
functions are well-defined and correctly implemented.x/token/types/msg_test.go (1)
389-389
: LGTM!The changes to the field name enhance clarity and align with its intended functionality.
Also applies to: 400-400
x/token/keeper/convert.go (4)
Line range hint
1-1
:
Verify the impact of telemetry removal on monitoring and performance analysis.The removal of telemetry tracking logic simplifies the function and reduces overhead. However, ensure that this change does not affect monitoring and performance analysis.
Line range hint
49-50
:
Verify the impact of telemetry removal on monitoring and performance analysis.The removal of telemetry tracking logic simplifies the function and reduces overhead. However, ensure that this change does not affect monitoring and performance analysis.
Line range hint
97-98
:
Verify the impact of telemetry removal on monitoring and performance analysis.The removal of telemetry tracking logic simplifies the function and reduces overhead. However, ensure that this change does not affect monitoring and performance analysis.
Line range hint
146-147
:
Verify the impact of telemetry removal on monitoring and performance analysis.The removal of telemetry tracking logic simplifies the function and reduces overhead. However, ensure that this change does not affect monitoring and performance analysis.
app/test_helper.go (6)
328-329
: LGTM!The addition of the
SignAndDeliver
function enhances testing capabilities by simulating transaction delivery. Ensure that the function works correctly and adheres to best practices.
244-245
: LGTM! But verify the function usage in the codebase.The change in the function signature aligns with the new package structure. Ensure that all function calls to
genesisStateWithValSet
match the new types.Verification successful
Verified: All function calls to
genesisStateWithValSet
inapp/test_helper.go
match the new typesLorenzoApp
andGenesisState
.
app/test_helper.go
: Verified function calls at lines 244-245 and other occurrences.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify all function calls to `genesisStateWithValSet` match the new types. # Test: Search for the function usage. Expect: Only occurances of the new types. rg --type go -A 5 $'genesisStateWithValSet'Length of output: 1131
81-82
: LGTM! But verify the function usage in the codebase.The change in the function signature aligns with the new package structure. Ensure that all function calls to
Setup
match the new return type.Verification successful
LGTM! But verify the function usage in the codebase.
The change in the function signature aligns with the new package structure. Ensure that all function calls to
Setup
match the new return type.
x/fee/keeper/keeper_test.go
:app := app.Setup(suite.T())
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify all function calls to `Setup` match the new return type. # Test: Search for the function usage. Expect: Only occurances of the new return type. rg --type go -A 5 $'Setup'Length of output: 29740
Script:
#!/bin/bash # Description: Search for all instances where the `Setup` function is called and check their context. # Test: Search for the `Setup` function calls. Expect: Only occurrences of the new return type. rg --type go 'Setup\(' -A 5Length of output: 1316
219-220
: LGTM! But verify the function usage in the codebase.The change in the function signature aligns with the new package structure. Ensure that all function calls to
setup
match the new return types.Verification successful
Verified: Function usage matches the new return types.
The change in the function signature aligns with the new package structure, and all instances of the
setup
function usage in the codebase match the new return types(*LorenzoApp, GenesisState)
.
app/test_helper.go
: Verified correct usage.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify all function calls to `setup` match the new return types. # Test: Search for the function usage. Expect: Only occurances of the new return types. rg --type go -A 5 $'setup'Length of output: 3960
Script:
#!/bin/bash # Description: Verify all function calls to `setup` match the new return types. # Check detailed usage of `setup` function in the mentioned files. rg --type go -A 5 'setup()' x/token/keeper/setup_test.go x/plan/keeper/keeper_test.go testutil/staking-rewards.go cmd/lorenzod/cmd/testnet.goLength of output: 3056
168-169
: LGTM! But verify the function usage in the codebase.The change in the function signature aligns with the new package structure. Ensure that all function calls to
SetupWithGenesisValSet
match the new return type.Verification successful
Let's verify the handling of the return type
*LorenzoApp
in the files whereSetupWithGenesisValSet
is used.
Let's verify the usage of the
app
variable intestutil/ibc/chain.go
to ensure it is handled as*LorenzoApp
.
Verified!
The function
SetupWithGenesisValSet
and its return type*LorenzoApp
are correctly handled in the codebase. The changes align with the new package structure and there are no type mismatches.
testutil/ibc/chain.go
: Theapp
variable is correctly used as*LorenzoApp
.testutil/ibc/app.go
: The function calls another function and returns its value, which is consistent.app/test_helper.go
: The function definition is consistent with the new return type.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify all function calls to `SetupWithGenesisValSet` match the new return type. # Test: Search for the function usage. Expect: Only occurances of the new return type. rg --type go -A 5 $'SetupWithGenesisValSet'Length of output: 2654
Script:
#!/bin/bash # Description: Verify the handling of the return type `*LorenzoApp` in the files where `SetupWithGenesisValSet` is used. # Check the handling in `testutil/ibc/chain.go` rg --type go -A 10 'SetupWithGenesisValSet' testutil/ibc/chain.go # Check the handling in `testutil/ibc/app.go` rg --type go -A 10 'SetupWithGenesisValSet' testutil/ibc/app.go # Check the handling in `app/test_helper.go` rg --type go -A 10 'SetupWithGenesisValSet' app/test_helper.goLength of output: 3062
Script:
#!/bin/bash # Description: Verify the usage of the `app` variable in `testutil/ibc/chain.go`. # Search for the `app` variable usage in `testutil/ibc/chain.go`. rg --type go -A 10 '\bapp\b' testutil/ibc/chain.goLength of output: 2161
111-112
: LGTM! But verify the function usage in the codebase.The change in the function signature aligns with the new package structure. Ensure that all function calls to
SetupWithGenesisMergeFn
match the new return type.x/token/keeper/msg_server_test.go (6)
591-592
: LGTM! But verify the parameter usage in the codebase.The renaming of the parameter
EnableConvert
toEnableConversion
enhances clarity regarding its purpose. Ensure that the changes are consistent across the codebase.
[approved
306-307
: LGTM! But verify the parameter usage in the codebase.The renaming of the parameter
EnableConvert
toEnableConversion
enhances clarity regarding its purpose. Ensure that the changes are consistent across the codebase.Verification successful
Verification Complete: Parameter Renaming Consistent
The renaming of the parameter
EnableConvert
toEnableConversion
is consistent across the codebase. No instances of the old parameter nameEnableConvert
were found, and multiple instances of the new parameter nameEnableConversion
were identified.
- All occurrences of
EnableConvert
have been successfully renamed toEnableConversion
.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify all instances of the parameter `EnableConvert` have been renamed to `EnableConversion`. # Test: Search for the old parameter name. Expect: No occurrences of the old parameter name. rg --type go -A 5 $'EnableConvert'Length of output: 33
Script:
#!/bin/bash # Description: Verify all instances of the parameter `EnableConvert` have been renamed to `EnableConversion`. # Test: Search for the old parameter name. Expect: No occurrences of the old parameter name. rg --type go -A 5 'EnableConvert' # Test: Search for the new parameter name. Expect: Occurrences of the new parameter name. rg --type go -A 5 'EnableConversion'Length of output: 7037
71-72
: LGTM! But verify the parameter usage in the codebase.The renaming of the parameter
EnableConvert
toEnableConversion
enhances clarity regarding its purpose. Ensure that the changes are consistent across the codebase.Verification successful
Verification successful!
The renaming of the parameter
EnableConvert
toEnableConversion
has been consistently applied across the codebase. No instances of the old parameter name were found.
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify all instances of the parameter `EnableConvert` have been renamed to `EnableConversion`. # Test: Search for the old parameter name. Expect: No occurrences of the old parameter name. rg --type go -A 5 $'EnableConvert'Length of output: 33
Script:
#!/bin/bash # Description: Verify all instances of the parameter `EnableConvert` have been renamed to `EnableConversion`. # Test: Search for the old parameter name and related terms. Expect: No occurrences of the old parameter name. rg --type go -A 10 'EnableConvert|EnableConversion'Length of output: 12176
185-186
: LGTM! But verify the parameter usage in the codebase.The renaming of the parameter
EnableConvert
toEnableConversion
enhances clarity regarding its purpose. Ensure that the changes are consistent across the codebase.Verification successful
LGTM! The parameter
EnableConvert
has been successfully renamed toEnableConversion
across the codebase.The renaming enhances clarity regarding its purpose, and the changes are consistent throughout the codebase.
- Verified in the following files:
x/token/types/params.go
x/token/types/msg_test.go
x/token/types/genesis.pb.go
x/token/keeper/params.go
x/token/keeper/msg_server_test.go
x/token/keeper/grpc_query_test.go
x/token/keeper/evm_hooks.go
x/ibctransfer/keeper/msg_server_test.go
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify all instances of the parameter `EnableConvert` have been renamed to `EnableConversion`. # Test: Search for the old parameter name. Expect: No occurrences of the old parameter name. rg --type go -A 5 $'EnableConvert'Length of output: 33
Script:
#!/bin/bash # Description: Verify all instances of the parameter `EnableConversion` in the codebase. # Test: Search for the new parameter name. Expect: Occurrences of the new parameter name. rg --type go -A 5 $'EnableConversion'Length of output: 7003
391-392
: LGTM! But verify the parameter usage in the codebase.The renaming of the parameter
EnableConvert
toEnableConversion
enhances clarity regarding its purpose. Ensure that the changes are consistent across the codebase.Verification successful
Renaming Verified: No issues found.
The parameter
EnableConvert
has been successfully renamed toEnableConversion
across the codebase. No instances of the old parameter name were found, and the new parameter name is used consistently.
- Verified files include:
x/token/keeper/params.go
x/token/keeper/msg_server_test.go
x/token/types/msg_test.go
x/token/types/genesis.pb.go
x/token/keeper/evm_hooks.go
x/token/types/params.go
x/token/keeper/grpc_query_test.go
x/ibctransfer/keeper/msg_server_test.go
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify all instances of the parameter `EnableConvert` have been renamed to `EnableConversion`. # Test: Search for the old parameter name. Expect: No occurrences of the old parameter name. rg --type go -A 5 $'EnableConvert'Length of output: 33
Script:
#!/bin/bash # Description: Verify all instances of the parameter `EnableConvert` have been renamed to `EnableConversion`. # Search for the old parameter name. Expect: No occurrences of the old parameter name. rg --type go -A 5 'EnableConvert' # Search for the new parameter name. Expect: Occurrences of the new parameter name. rg --type go -A 5 'EnableConversion'Length of output: 7037
418-419
: LGTM! But verify the parameter usage in the codebase.The renaming of the parameter
EnableConvert
toEnableConversion
enhances clarity regarding its purpose. Ensure that the changes are consistent across the codebase.Verification successful
Verification successful!
The parameter
EnableConvert
has been consistently renamed toEnableConversion
across the codebase.
x/token/keeper/params.go
x/token/keeper/msg_server_test.go
x/token/keeper/grpc_query_test.go
x/token/keeper/evm_hooks.go
x/token/types/msg_test.go
x/token/types/params.go
x/token/types/genesis.pb.go
x/ibctransfer/keeper/msg_server_test.go
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify all instances of the parameter `EnableConvert` have been renamed to `EnableConversion`. # Test: Search for the old parameter name. Expect: No occurrences of the old parameter name. rg --type go -A 5 $'EnableConvert'Length of output: 33
Script:
#!/bin/bash # Description: Verify all instances of the parameter `EnableConvert` have been renamed to `EnableConversion`. # Test: Search for the old parameter name. Expect: No occurrences of the old parameter name. rg --type go -A 5 'EnableConvert' # Test: Search for the new parameter name. Expect: Occurrences of the new parameter name. rg --type go -A 5 'EnableConversion'Length of output: 7037
app/app.go (2)
115-115
: Verify the necessity of the new import.Ensure that the new import statement for the token package is necessary and used within the file.
Verification successful
The new import statement for the token package is necessary.
The token package is utilized at line 520 in the
app/app.go
file, confirming the need for the import statement.
app/app.go
, line 520:transferStack := token.NewIBCMiddleware(ics20wrapperModule, app.TokenKeeper)
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the usage of the new token package import. # Test: Search for the usage of the token package. Expect: At least one usage. rg --type go --no-filename --line-number 'token\.' app/app.goLength of output: 145
519-520
: Verify the correctness and impact of the IBC middleware refactoring.Ensure that the refactoring of the IBC middleware setup is correct and does not negatively impact the existing functionality.
testutil/ibc/chain.go (10)
101-165
: LGTM!The function
NewTestChainWithValSet
correctly initializes a newTestChain
instance with the given validator set and signer array.
168-192
: LGTM!The function
NewTestChain
correctly initializes a new test chain with a default of 4 validators.
194-197
: LGTM!The function
GetContext
correctly returns the current context for the application.
199-207
: LGTM!The function
GetSimApp
correctly returns theSimApp
to allow usage of non-interface fields.
209-213
: LGTM!The function
QueryProof
correctly performs an ABCI query with the given key and returns the proto encoded merkle proof for the query.
215-220
: LGTM!The function
QueryProofAtHeight
correctly performs an ABCI query with the given key at a specific height and returns the proto encoded merkle proof for the query.
222-244
: LGTM!The function
QueryProofForStore
correctly performs an ABCI query with the given key for a specific store and returns the proto encoded merkle proof for the query.
246-268
: LGTM!The function
QueryUpgradeProof
correctly performs an ABCI query with the given key for an upgrade proof and returns the proto encoded merkle proof for the query.
270-280
: LGTM!The function
QueryConsensusStateProof
correctly performs an ABCI query for a consensus state stored on the given clientID and returns the proof and consensusHeight.
282-317
: LGTM!The function
NextBlock
correctly sets the last header to the current header and increments the current header to be at the next block height.testutil/ibc/endpoint.go (10)
36-48
: LGTM!The function
NewEndpoint
correctly constructs a new endpoint without the counterparty.
50-59
: LGTM!The function
NewDefaultEndpoint
correctly constructs a new endpoint using default values.
61-69
: LGTM!The function
QueryProof
correctly queries proof associated with the endpoint using the latest client state height on the counterparty chain.
71-76
: LGTM!The function
QueryProofAtHeight
correctly queries proof associated with the endpoint using the provided proof height.
78-128
: LGTM!The function
CreateClient
correctly creates an IBC client on the endpoint and updates the clientID if the message is successfully executed.
130-156
: LGTM!The function
UpdateClient
correctly updates the IBC client associated with the endpoint.
158-210
: LGTM!The function
UpgradeChain
correctly upgrades a chain's chainID to the next revision number and updates the counterparty client.
212-229
: LGTM!The function
ConnOpenInit
correctly constructs and executes aMsgConnectionOpenInit
on the associated endpoint.
231-256
: LGTM!The function
ConnOpenTry
correctly constructs and executes aMsgConnectionOpenTry
on the associated endpoint.
258-273
: LGTM!The function
ConnOpenAck
correctly constructs and executes aMsgConnectionOpenAck
on the associated endpoint.testutil/ibc/solomachine.go (5)
97-100
: LGTM!The function is straightforward and correctly returns a new solo machine
ClientState
instance.
102-111
: LGTM!The function is straightforward and correctly returns a new solo machine
ConsensusState
instance.
114-117
: LGTM!The function is straightforward and correctly returns an exported
Height
withSequence
asRevisionHeight
.
344-359
: **Handle potential errors
68-95
: Add error handling for key generation inGenerateKeys
.The function does not handle potential errors from key generation. Consider adding error handling to improve robustness.
func GenerateKeys(t *testing.T, n uint64) ([]cryptotypes.PrivKey, []cryptotypes.PubKey, cryptotypes.PubKey, error) { require.NotEqual(t, uint64(0), n, "generation of zero keys is not allowed") privKeys := make([]cryptotypes.PrivKey, n) pubKeys := make([]cryptotypes.PubKey, n) for i := uint64(0); i < n; i++ { privKeys[i] = secp256k1.GenPrivKey() pubKeys[i] = privKeys[i].PubKey() } var pk cryptotypes.PubKey if len(privKeys) > 1 { // generate multi sig pk pk = kmultisig.NewLegacyAminoPubKey(int(n), pubKeys) } else { pk = privKeys[0].PubKey() } return privKeys, pubKeys, pk, nil }Likely invalid or redundant comment.
@@ -0,0 +1,7 @@ | |||
# IBC Testing | |||
|
|||
This package contains the necessary code to test the IBC modules. It is a forked version of IBC Testing, customized for Lorenzo. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reduce line length.
The lines exceed the recommended length of 120 characters. Consider breaking them into multiple lines.
- This package contains the necessary code to test the IBC modules. It is a forked version of IBC Testing, customized for Lorenzo.
+ This package contains the necessary code to test the IBC modules.
+ It is a forked version of IBC Testing, customized for Lorenzo.
- The customization aims to maximize compatibility with the original source code while ensuring it is suitably adapted for Lorenzo’s specific requirements.
+ The customization aims to maximize compatibility with the original source code
+ while ensuring it is suitably adapted for Lorenzo’s specific requirements.
- The maintainer must keep it updated with the currently used version of the IBC code repository to ensure ongoing compatibility and functionality.
+ The maintainer must keep it updated with the currently used version of the IBC code repository
+ to ensure ongoing compatibility and functionality.
Also applies to: 5-5, 7-7
Tools
Markdownlint
3-3: Expected: 0 or 2; Actual: 1
Trailing spaces(MD009, no-trailing-spaces)
3-3: Expected: 120; Actual: 129
Line length(MD013, line-length)
Remove trailing spaces.
There are trailing spaces at the end of this line.
- This package contains the necessary code to test the IBC modules. It is a forked version of IBC Testing, customized for Lorenzo.
+ This package contains the necessary code to test the IBC modules. It is a forked version of IBC Testing, customized for Lorenzo.
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. Thoroughly test & benchmark the code to ensure it meets the requirements.
This package contains the necessary code to test the IBC modules. It is a forked version of IBC Testing, customized for Lorenzo. | |
This package contains the necessary code to test the IBC modules. It is a forked version of IBC Testing, customized for Lorenzo. |
Tools
Markdownlint
3-3: Expected: 0 or 2; Actual: 1
Trailing spaces(MD009, no-trailing-spaces)
3-3: Expected: 120; Actual: 129
Line length(MD013, line-length)
|
||
The customization aims to maximize compatibility with the original source code while ensuring it is suitably adapted for Lorenzo’s specific requirements. | ||
|
||
The maintainer must keep it updated with the currently used version of the IBC code repository to ensure ongoing compatibility and functionality. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a newline at the end of the file.
Files should end with a single newline character.
- to ensure ongoing compatibility and functionality.
+ to ensure ongoing compatibility and functionality.
+
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. Thoroughly test & benchmark the code to ensure it meets the requirements.
The maintainer must keep it updated with the currently used version of the IBC code repository to ensure ongoing compatibility and functionality. | |
The maintainer must keep it updated with the currently used version of the IBC code repository to ensure ongoing compatibility and functionality. | |
Tools
Markdownlint
7-7: Expected: 120; Actual: 145
Line length(MD013, line-length)
7-7: null
Files should end with a single newline character(MD047, single-trailing-newline)
// CreateHeader generates a new private/public key pair and creates the | ||
// necessary signature to construct a valid solo machine header. | ||
// A new diversifier will be used as well | ||
func (solo *Solomachine) CreateHeader(newDiversifier string) *solomachine.Header { | ||
// generate new private keys and signature for header | ||
newPrivKeys, newPubKeys, newPubKey := GenerateKeys(solo.t, uint64(len(solo.PrivateKeys))) | ||
|
||
publicKey, err := codectypes.NewAnyWithValue(newPubKey) | ||
require.NoError(solo.t, err) | ||
|
||
data := &solomachine.HeaderData{ | ||
NewPubKey: publicKey, | ||
NewDiversifier: newDiversifier, | ||
} | ||
|
||
dataBz, err := solo.cdc.Marshal(data) | ||
require.NoError(solo.t, err) | ||
|
||
signBytes := &solomachine.SignBytes{ | ||
Sequence: solo.Sequence, | ||
Timestamp: solo.Time, | ||
Diversifier: solo.Diversifier, | ||
Path: []byte(solomachine.SentinelHeaderPath), | ||
Data: dataBz, | ||
} | ||
|
||
bz, err := solo.cdc.Marshal(signBytes) | ||
require.NoError(solo.t, err) | ||
|
||
sig := solo.GenerateSignature(bz) | ||
|
||
header := &solomachine.Header{ | ||
Timestamp: solo.Time, | ||
Signature: sig, | ||
NewPublicKey: publicKey, | ||
NewDiversifier: newDiversifier, | ||
} | ||
|
||
// assumes successful header update | ||
solo.Sequence++ | ||
solo.Time++ | ||
solo.PrivateKeys = newPrivKeys | ||
solo.PublicKeys = newPubKeys | ||
solo.PublicKey = newPubKey | ||
solo.Diversifier = newDiversifier | ||
|
||
return header |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle potential errors more explicitly in CreateHeader
.
The function should handle potential errors more explicitly to improve robustness.
func (solo *Solomachine) CreateHeader(newDiversifier string) *solomachine.Header {
// generate new private keys and signature for header
newPrivKeys, newPubKeys, newPubKey := GenerateKeys(solo.t, uint64(len(solo.PrivateKeys)))
publicKey, err := codectypes.NewAnyWithValue(newPubKey)
require.NoError(solo.t, err)
data := &solomachine.HeaderData{
NewPubKey: publicKey,
NewDiversifier: newDiversifier,
}
dataBz, err := solo.cdc.Marshal(data)
require.NoError(solo.t, err)
signBytes := &solomachine.SignBytes{
Sequence: solo.Sequence,
Timestamp: solo.Time,
Diversifier: solo.Diversifier,
Path: []byte(solomachine.SentinelHeaderPath),
Data: dataBz,
}
bz, err := solo.cdc.Marshal(signBytes)
require.NoError(solo.t, err)
sig := solo.GenerateSignature(bz)
header := &solomachine.Header{
Timestamp: solo.Time,
Signature: sig,
NewPublicKey: publicKey,
NewDiversifier: newDiversifier,
}
// assumes successful header update
solo.Sequence++
solo.Time++
solo.PrivateKeys = newPrivKeys
solo.PublicKeys = newPubKeys
solo.PublicKey = newPubKey
solo.Diversifier = newDiversifier
return header
}
Committable suggestion was skipped due to low confidence.
// CreateMisbehaviour constructs testing misbehaviour for the solo machine client | ||
// by signing over two different data bytes at the same sequence. | ||
func (solo *Solomachine) CreateMisbehaviour() *solomachine.Misbehaviour { | ||
merklePath := solo.GetClientStatePath("counterparty") | ||
path, err := solo.cdc.Marshal(&merklePath) | ||
require.NoError(solo.t, err) | ||
|
||
data, err := solo.cdc.Marshal(solo.ClientState()) | ||
require.NoError(solo.t, err) | ||
|
||
signBytes := &solomachine.SignBytes{ | ||
Sequence: solo.Sequence, | ||
Timestamp: solo.Time, | ||
Diversifier: solo.Diversifier, | ||
Path: path, | ||
Data: data, | ||
} | ||
|
||
bz, err := solo.cdc.Marshal(signBytes) | ||
require.NoError(solo.t, err) | ||
|
||
sig := solo.GenerateSignature(bz) | ||
signatureOne := solomachine.SignatureAndData{ | ||
Signature: sig, | ||
Path: path, | ||
Data: data, | ||
Timestamp: solo.Time, | ||
} | ||
|
||
// misbehaviour signaturess can have different timestamps | ||
solo.Time++ | ||
|
||
merklePath = solo.GetConsensusStatePath("counterparty", clienttypes.NewHeight(0, 1)) | ||
path, err = solo.cdc.Marshal(&merklePath) | ||
require.NoError(solo.t, err) | ||
|
||
data, err = solo.cdc.Marshal(solo.ConsensusState()) | ||
require.NoError(solo.t, err) | ||
|
||
signBytes = &solomachine.SignBytes{ | ||
Sequence: solo.Sequence, | ||
Timestamp: solo.Time, | ||
Diversifier: solo.Diversifier, | ||
Path: path, | ||
Data: data, | ||
} | ||
|
||
bz, err = solo.cdc.Marshal(signBytes) | ||
require.NoError(solo.t, err) | ||
|
||
sig = solo.GenerateSignature(bz) | ||
signatureTwo := solomachine.SignatureAndData{ | ||
Signature: sig, | ||
Path: path, | ||
Data: data, | ||
Timestamp: solo.Time, | ||
} | ||
|
||
return &solomachine.Misbehaviour{ | ||
Sequence: solo.Sequence, | ||
SignatureOne: &signatureOne, | ||
SignatureTwo: &signatureTwo, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle potential errors more explicitly in CreateMisbehaviour
.
The function should handle potential errors more explicitly to improve robustness.
func (solo *Solomachine) CreateMisbehaviour() *solomachine.Misbehaviour {
merklePath := solo.GetClientStatePath("counterparty")
path, err := solo.cdc.Marshal(&merklePath)
require.NoError(solo.t, err)
data, err := solo.cdc.Marshal(solo.ClientState())
require.NoError(solo.t, err)
signBytes := &solomachine.SignBytes{
Sequence: solo.Sequence,
Timestamp: solo.Time,
Diversifier: solo.Diversifier,
Path: path,
Data: data,
}
bz, err := solo.cdc.Marshal(signBytes)
require.NoError(solo.t, err)
sig := solo.GenerateSignature(bz)
signatureOne := solomachine.SignatureAndData{
Signature: sig,
Path: path,
Data: data,
Timestamp: solo.Time,
}
// misbehaviour signaturess can have different timestamps
solo.Time++
merklePath = solo.GetConsensusStatePath("counterparty", clienttypes.NewHeight(0, 1))
path, err = solo.cdc.Marshal(&merklePath)
require.NoError(solo.t, err)
data, err = solo.cdc.Marshal(solo.ConsensusState())
require.NoError(solo.t, err)
signBytes = &solomachine.SignBytes{
Sequence: solo.Sequence,
Timestamp: solo.Time,
Diversifier: solo.Diversifier,
Path: path,
Data: data,
}
bz, err = solo.cdc.Marshal(signBytes)
require.NoError(solo.t, err)
sig = solo.GenerateSignature(bz)
signatureTwo := solomachine.SignatureAndData{
Signature: sig,
Path: path,
Data: data,
Timestamp: solo.Time,
}
return &solomachine.Misbehaviour{
Sequence: solo.Sequence,
SignatureOne: &signatureOne,
SignatureTwo: &signatureTwo,
}
}
Committable suggestion was skipped due to low confidence.
// CreateClient creates an on-chain client on the provided chain. | ||
func (solo *Solomachine) CreateClient(chain *TestChain) string { | ||
msgCreateClient, err := clienttypes.NewMsgCreateClient(solo.ClientState(), solo.ConsensusState(), chain.SenderAccount.GetAddress().String()) | ||
require.NoError(solo.t, err) | ||
|
||
res, err := chain.SendMsgs(msgCreateClient) | ||
require.NoError(solo.t, err) | ||
require.NotNil(solo.t, res) | ||
|
||
clientID, err := ParseClientIDFromEvents(res.GetEvents()) | ||
require.NoError(solo.t, err) | ||
|
||
return clientID | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle potential errors more explicitly in CreateClient
.
The function should handle potential errors more explicitly to improve robustness.
func (solo *Solomachine) CreateClient(chain *TestChain) string {
msgCreateClient, err := clienttypes.NewMsgCreateClient(solo.ClientState(), solo.ConsensusState(), chain.SenderAccount.GetAddress().String())
require.NoError(solo.t, err)
res, err := chain.SendMsgs(msgCreateClient)
require.NoError(solo.t, err)
require.NotNil(solo.t, res)
clientID, err := ParseClientIDFromEvents(res.GetEvents())
require.NoError(solo.t, err)
require.NotEmpty(solo.t, clientID, "clientID should not be empty")
return clientID
}
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. Thoroughly test & benchmark the code to ensure it meets the requirements.
// CreateClient creates an on-chain client on the provided chain. | |
func (solo *Solomachine) CreateClient(chain *TestChain) string { | |
msgCreateClient, err := clienttypes.NewMsgCreateClient(solo.ClientState(), solo.ConsensusState(), chain.SenderAccount.GetAddress().String()) | |
require.NoError(solo.t, err) | |
res, err := chain.SendMsgs(msgCreateClient) | |
require.NoError(solo.t, err) | |
require.NotNil(solo.t, res) | |
clientID, err := ParseClientIDFromEvents(res.GetEvents()) | |
require.NoError(solo.t, err) | |
return clientID | |
} | |
// CreateClient creates an on-chain client on the provided chain. | |
func (solo *Solomachine) CreateClient(chain *TestChain) string { | |
msgCreateClient, err := clienttypes.NewMsgCreateClient(solo.ClientState(), solo.ConsensusState(), chain.SenderAccount.GetAddress().String()) | |
require.NoError(solo.t, err) | |
res, err := chain.SendMsgs(msgCreateClient) | |
require.NoError(solo.t, err) | |
require.NotNil(solo.t, res) | |
clientID, err := ParseClientIDFromEvents(res.GetEvents()) | |
require.NoError(solo.t, err) | |
require.NotEmpty(solo.t, clientID, "clientID should not be empty") | |
return clientID | |
} |
// NewSolomachine returns a new solomachine instance with an `nKeys` amount of | ||
// generated private/public key pairs and a sequence starting at 1. If nKeys | ||
// is greater than 1 then a multisig public key is used. | ||
func NewSolomachine(t *testing.T, cdc codec.BinaryCodec, clientID, diversifier string, nKeys uint64) *Solomachine { | ||
privKeys, pubKeys, pk := GenerateKeys(t, nKeys) | ||
|
||
return &Solomachine{ | ||
t: t, | ||
cdc: cdc, | ||
ClientID: clientID, | ||
PrivateKeys: privKeys, | ||
PublicKeys: pubKeys, | ||
PublicKey: pk, | ||
Sequence: 1, | ||
Time: 10, | ||
Diversifier: diversifier, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure proper error handling in the constructor function NewSolomachine
.
The function does not handle potential errors from GenerateKeys
. Consider adding error handling to improve robustness.
func NewSolomachine(t *testing.T, cdc codec.BinaryCodec, clientID, diversifier string, nKeys uint64) *Solomachine {
- privKeys, pubKeys, pk := GenerateKeys(t, nKeys)
+ privKeys, pubKeys, pk, err := GenerateKeys(t, nKeys)
+ require.NoError(t, err)
return &Solomachine{
t: t,
cdc: cdc,
ClientID: clientID,
PrivateKeys: privKeys,
PublicKeys: pubKeys,
PublicKey: pk,
Sequence: 1,
Time: 10,
Diversifier: diversifier,
}
}
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. Thoroughly test & benchmark the code to ensure it meets the requirements.
// NewSolomachine returns a new solomachine instance with an `nKeys` amount of | |
// generated private/public key pairs and a sequence starting at 1. If nKeys | |
// is greater than 1 then a multisig public key is used. | |
func NewSolomachine(t *testing.T, cdc codec.BinaryCodec, clientID, diversifier string, nKeys uint64) *Solomachine { | |
privKeys, pubKeys, pk := GenerateKeys(t, nKeys) | |
return &Solomachine{ | |
t: t, | |
cdc: cdc, | |
ClientID: clientID, | |
PrivateKeys: privKeys, | |
PublicKeys: pubKeys, | |
PublicKey: pk, | |
Sequence: 1, | |
Time: 10, | |
Diversifier: diversifier, | |
} | |
// NewSolomachine returns a new solomachine instance with an `nKeys` amount of | |
// generated private/public key pairs and a sequence starting at 1. If nKeys | |
// is greater than 1 then a multisig public key is used. | |
func NewSolomachine(t *testing.T, cdc codec.BinaryCodec, clientID, diversifier string, nKeys uint64) *Solomachine { | |
privKeys, pubKeys, pk, err := GenerateKeys(t, nKeys) | |
require.NoError(t, err) | |
return &Solomachine{ | |
t: t, | |
cdc: cdc, | |
ClientID: clientID, | |
PrivateKeys: privKeys, | |
PublicKeys: pubKeys, | |
PublicKey: pk, | |
Sequence: 1, | |
Time: 10, | |
Diversifier: diversifier, | |
} | |
} |
// ConnOpenAck performs the connection open ack handshake step on the tendermint chain for the associated | ||
// solo machine client. | ||
func (solo *Solomachine) ConnOpenAck(chain *TestChain, clientID, connectionID string) { | ||
proofTry := solo.GenerateConnOpenTryProof(clientID, connectionID) | ||
|
||
clientState := ibctm.NewClientState(chain.ChainID, DefaultTrustLevel, TrustingPeriod, UnbondingPeriod, MaxClockDrift, chain.LastHeader.GetHeight().(clienttypes.Height), commitmenttypes.GetSDKSpecs(), UpgradePath) | ||
proofClient := solo.GenerateClientStateProof(clientState) | ||
|
||
consensusState := chain.LastHeader.ConsensusState() | ||
consensusHeight := chain.LastHeader.GetHeight() | ||
proofConsensus := solo.GenerateConsensusStateProof(consensusState, consensusHeight) | ||
|
||
msgConnOpenAck := connectiontypes.NewMsgConnectionOpenAck( | ||
connectionID, connectionIDSolomachine, clientState, | ||
proofTry, proofClient, proofConsensus, | ||
clienttypes.ZeroHeight(), clientState.GetLatestHeight().(clienttypes.Height), | ||
ConnectionVersion, | ||
chain.SenderAccount.GetAddress().String(), | ||
) | ||
|
||
res, err := chain.SendMsgs(msgConnOpenAck) | ||
require.NoError(solo.t, err) | ||
require.NotNil(solo.t, res) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle potential errors more explicitly in ConnOpenAck
.
The function should handle potential errors more explicitly to improve robustness.
func (solo *Solomachine) ConnOpenAck(chain *TestChain, clientID, connectionID string) {
proofTry := solo.GenerateConnOpenTryProof(clientID, connectionID)
clientState := ibctm.NewClientState(chain.ChainID, DefaultTrustLevel, TrustingPeriod, UnbondingPeriod, MaxClockDrift, chain.LastHeader.GetHeight().(clienttypes.Height), commitmenttypes.GetSDKSpecs(), UpgradePath)
proofClient := solo.GenerateClientStateProof(clientState)
consensusState := chain.LastHeader.ConsensusState()
consensusHeight := chain.LastHeader.GetHeight()
proofConsensus := solo.GenerateConsensusStateProof(consensusState, consensusHeight)
msgConnOpenAck := connectiontypes.NewMsgConnectionOpenAck(
connectionID, connectionIDSolomachine, clientState,
proofTry, proofClient, proofConsensus,
clienttypes.ZeroHeight(), clientState.GetLatestHeight().(clienttypes.Height),
ConnectionVersion,
chain.SenderAccount.GetAddress().String(),
)
res, err := chain.SendMsgs(msgConnOpenAck)
require.NoError(solo.t, err)
require.NotNil(solo.t, res)
require.NotEmpty(solo.t, res, "response should not be empty")
}
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. Thoroughly test & benchmark the code to ensure it meets the requirements.
// ConnOpenAck performs the connection open ack handshake step on the tendermint chain for the associated | |
// solo machine client. | |
func (solo *Solomachine) ConnOpenAck(chain *TestChain, clientID, connectionID string) { | |
proofTry := solo.GenerateConnOpenTryProof(clientID, connectionID) | |
clientState := ibctm.NewClientState(chain.ChainID, DefaultTrustLevel, TrustingPeriod, UnbondingPeriod, MaxClockDrift, chain.LastHeader.GetHeight().(clienttypes.Height), commitmenttypes.GetSDKSpecs(), UpgradePath) | |
proofClient := solo.GenerateClientStateProof(clientState) | |
consensusState := chain.LastHeader.ConsensusState() | |
consensusHeight := chain.LastHeader.GetHeight() | |
proofConsensus := solo.GenerateConsensusStateProof(consensusState, consensusHeight) | |
msgConnOpenAck := connectiontypes.NewMsgConnectionOpenAck( | |
connectionID, connectionIDSolomachine, clientState, | |
proofTry, proofClient, proofConsensus, | |
clienttypes.ZeroHeight(), clientState.GetLatestHeight().(clienttypes.Height), | |
ConnectionVersion, | |
chain.SenderAccount.GetAddress().String(), | |
) | |
res, err := chain.SendMsgs(msgConnOpenAck) | |
require.NoError(solo.t, err) | |
require.NotNil(solo.t, res) | |
} | |
// ConnOpenAck performs the connection open ack handshake step on the tendermint chain for the associated | |
// solo machine client. | |
func (solo *Solomachine) ConnOpenAck(chain *TestChain, clientID, connectionID string) { | |
proofTry := solo.GenerateConnOpenTryProof(clientID, connectionID) | |
clientState := ibctm.NewClientState(chain.ChainID, DefaultTrustLevel, TrustingPeriod, UnbondingPeriod, MaxClockDrift, chain.LastHeader.GetHeight().(clienttypes.Height), commitmenttypes.GetSDKSpecs(), UpgradePath) | |
proofClient := solo.GenerateClientStateProof(clientState) | |
consensusState := chain.LastHeader.ConsensusState() | |
consensusHeight := chain.LastHeader.GetHeight() | |
proofConsensus := solo.GenerateConsensusStateProof(consensusState, consensusHeight) | |
msgConnOpenAck := connectiontypes.NewMsgConnectionOpenAck( | |
connectionID, connectionIDSolomachine, clientState, | |
proofTry, proofClient, proofConsensus, | |
clienttypes.ZeroHeight(), clientState.GetLatestHeight().(clienttypes.Height), | |
ConnectionVersion, | |
chain.SenderAccount.GetAddress().String(), | |
) | |
res, err := chain.SendMsgs(msgConnOpenAck) | |
require.NoError(solo.t, err) | |
require.NotNil(solo.t, res) | |
require.NotEmpty(solo.t, res, "response should not be empty") | |
} |
}, | ||
} | ||
|
||
for _, tc := range testCases { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding more test cases.
The current test cases cover basic scenarios. Consider adding more test cases to cover edge cases and error conditions.
}, | ||
} | ||
|
||
for _, tc := range testCases { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding more test cases.
The current test cases cover basic scenarios. Consider adding more test cases to cover edge cases and error conditions.
err = errorsmod.Wrapf(errortypes.ErrInvalidType, "cannot unmarshal ICS-20 transfer packet data") | ||
return channeltypes.NewErrorAcknowledgement(err) | ||
} | ||
transfertypes.ModuleCdc.MustUnmarshalJSON(packet.GetData(), &data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider handling errors explicitly instead of using MustUnmarshalJSON
.
Using MustUnmarshalJSON
simplifies the control flow but can cause the application to panic if invalid data is encountered. Consider handling errors explicitly to improve robustness.
- transfertypes.ModuleCdc.MustUnmarshalJSON(packet.GetData(), &data)
+ if err := transfertypes.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil {
+ return channeltypes.NewErrorAcknowledgement(err)
+ }
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. Thoroughly test & benchmark the code to ensure it meets the requirements.
transfertypes.ModuleCdc.MustUnmarshalJSON(packet.GetData(), &data) | |
transfertypes.ModuleCdc.MustUnmarshalJSON(packet.GetData(), &data) | |
if err := transfertypes.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil { | |
return channeltypes.NewErrorAcknowledgement(err) | |
} |
Summary by CodeRabbit
New Features
Bug Fixes
enable_convert
toenable_conversion
.Documentation
Refactor