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

#107/ Update GetNodeVersionInfo response object #117

Merged
merged 33 commits into from
Oct 17, 2024

Conversation

lealobanov
Copy link
Collaborator

@lealobanov lealobanov commented Oct 5, 2024

Closes: #107

Description

Setup classes to model protobuf objects:

  • FlowNodeVersionInfo
  • FlowCompatibleRange

The JVM SDK currently does not support the Access API endpoint:

func (c *Client) GetNodeVersionInfo(ctx context.Context) (*flow.NodeVersionInfo, error) {
	return c.grpc.GetNodeVersionInfo(ctx)
}

PR to update protobuf files: onflow/flow#1516

To-do:

  • Run release for org.onflow:flow:1.0.0" as protobuf fields have changed since then: https://mvnrepository.com/artifact/org.onflow/flow
  • Add missing Access API endpoints
  • Add unit tests for new classes
  • Add unit tests for new Access API methods
  • Add integration tests for new Access API methods
  • Add examples for getNodeVersionInfo + update docs

For contributor use:

  • Targeted PR against master branch
  • Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
  • Code follows the standards mentioned here.
  • Updated relevant documentation
  • Re-reviewed Files changed in the Github PR explorer
  • Added appropriate labels

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced functionality to retrieve node version information via the Flow Access API.
    • Added new classes and methods in both Java and Kotlin to facilitate this feature.
    • Enhanced data models to support node version information and compatible ranges.
  • Tests

    • Implemented comprehensive test coverage for the new node version retrieval functionality in both Java and Kotlin.
    • Added unit tests for the new data classes to ensure correctness.
  • Chores

    • Updated dependency version for the Flow SDK library.
    • Introduced a new integration test task to enhance testing capabilities.
    • Added a new entry to the .gitignore file to exclude specific error files.

Copy link
Contributor

coderabbitai bot commented Oct 5, 2024

Walkthrough

A new Java class GetNodeVersionInfoAccessAPIConnector and a corresponding Kotlin class have been introduced to interact with the Flow Access API for retrieving node version information. Both classes include methods to fetch this information and handle responses appropriately. Additionally, new test classes for both Java and Kotlin implementations have been created to ensure the functionality works as expected. The SDK has also been updated to include new methods in the FlowAccessApi and AsyncFlowAccessApi interfaces, along with associated data classes for handling node version details.

Changes

File Change Summary
java-example/src/main/java/org/onflow/examples/java/getNodeVersionInfo/GetNodeVersionInfoAccessAPIConnector.java Added GetNodeVersionInfoAccessAPIConnector class with method getNodeVersionInfo().
java-example/src/test/java/org/onflow/examples/java/getNodeVersionInfo/GetNodeVersionInfoAccessAPIConnectorTest.java Created test class for GetNodeVersionInfoAccessAPIConnector with method canFetchNodeVersionInfo.
kotlin-example/src/main/kotlin/org/onflow/examples/kotlin/getNodeVersionInfo/GetNodeVersionInfoAccessAPIConnector.kt Added GetNodeVersionInfoAccessAPIConnector class with method getNodeVersionInfo().
kotlin-example/src/test/kotlin/org/onflow/examples/kotlin/getNodeVersionInfo/GetNodeVersionInfoAccessAPIConnectorTest.kt Created test class for Kotlin implementation with method Can fetch node version info.
sdk/build.gradle.kts Updated org.onflow:flow dependency version from 1.0.0 to 1.1.0.
sdk/src/main/kotlin/org/onflow/flow/sdk/AsyncFlowAccessApi.kt Added getNodeVersionInfo() method to AsyncFlowAccessApi interface.
sdk/src/main/kotlin/org/onflow/flow/sdk/FlowAccessApi.kt Added getNodeVersionInfo() method to FlowAccessApi interface.
sdk/src/main/kotlin/org/onflow/flow/sdk/impl/AsyncFlowAccessApiImpl.kt Implemented getNodeVersionInfo() method in AsyncFlowAccessApiImpl.
sdk/src/main/kotlin/org/onflow/flow/sdk/impl/FlowAccessApiImpl.kt Implemented getNodeVersionInfo() method in FlowAccessApiImpl.
sdk/src/main/kotlin/org/onflow/flow/sdk/models.kt Added FlowCompatibleRange and FlowNodeVersionInfo data classes.
sdk/src/test/kotlin/org/onflow/flow/sdk/impl/AsyncFlowAccessApiImplTest.kt Added test method for getNodeVersionInfo() in AsyncFlowAccessApiImplTest.
sdk/src/test/kotlin/org/onflow/flow/sdk/impl/FlowAccessApiImplTest.kt Added test method for getNodeVersionInfo() in FlowAccessApiImplTest.
sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowNodeVersionInfoTest.kt Created tests for FlowNodeVersionInfo and FlowCompatibleRange classes.

Assessment against linked issues

Objective Addressed Explanation
Update GetNodeVersionInfo response object (#107)

Possibly related issues

Possibly related PRs

Suggested reviewers

  • franklywatson
  • jribbink

🐰 In the meadow, I hop and play,
New classes bloom in a bright array.
Fetching versions, swift and neat,
With tests in place, our work's complete!
Hooray for code, so fresh and new,
A joyful leap, just for you! 🌼


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between fc88f83 and 7bd3078.

📒 Files selected for processing (1)
  • .gitignore (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • .gitignore

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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

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

CodeRabbit Commands (Invoked using PR comments)

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

Other keywords and placeholders

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

CodeRabbit Configuration File (.coderabbit.yaml)

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

Documentation and Community

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

Copy link

github-actions bot commented Oct 5, 2024

Unit Test Results

  60 files  ±0    60 suites  ±0   24s ⏱️ ±0s
340 tests ±0  339 ✔️ ±0  0 💤 ±0  1 ❌ ±0 

For more details on these failures, see this check.

Results for commit db9e3d1. ± Comparison against base commit db9e3d1.

♻️ This comment has been updated with latest results.

Copy link

github-actions bot commented Oct 5, 2024

Integration Test Results

0 files  ±0  0 suites  ±0   0s ⏱️ ±0s
0 tests ±0  0 ✔️ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit db9e3d1. ± Comparison against base commit db9e3d1.

♻️ This comment has been updated with latest results.

@lealobanov lealobanov self-assigned this Oct 5, 2024
Copy link

github-actions bot commented Oct 5, 2024

SDK Examples Unit Test Results

37 files  37 suites   6m 18s ⏱️
70 tests 70 ✔️ 0 💤 0 ❌

Results for commit fc88f83.

♻️ This comment has been updated with latest results.

Copy link

github-actions bot commented Oct 5, 2024

Common Integration Test Results

1 files  1 suites   7s ⏱️
1 tests 1 ✔️ 0 💤 0 ❌

Results for commit fc88f83.

♻️ This comment has been updated with latest results.

@lealobanov lealobanov force-pushed the get-node-version-info-protobuf-schema branch from 8275806 to 97ed1d5 Compare October 5, 2024 17:39
@lealobanov lealobanov marked this pull request as ready for review October 8, 2024 14:31
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

🧹 Outside diff range and nitpick comments (18)
kotlin-example/src/main/kotlin/org/onflow/examples/kotlin/getNodeVersionInfo/GetNodeVersionInfoAccessAPIConnector.kt (2)

9-14: LGTM: Method implementation is correct. Consider adding KDoc.

The getNodeVersionInfo() method correctly handles both success and error cases from the API call. It follows Kotlin best practices and is concisely implemented.

Consider adding KDoc to the method to provide more context and usage information. For example:

/**
 * Retrieves the node version information from the Flow Access API.
 *
 * @return FlowNodeVersionInfo containing the node version details.
 * @throws Exception if the API call fails, with the error message and associated throwable.
 */
fun getNodeVersionInfo(): FlowNodeVersionInfo {
    // ... existing implementation ...
}

1-15: Overall implementation looks good and aligns with PR objectives.

The GetNodeVersionInfoAccessAPIConnector class provides a clean and efficient way to interact with the Flow Access API for retrieving node version information. The implementation is concise, follows Kotlin best practices, and correctly handles both success and error scenarios.

This implementation aligns well with the PR objectives of updating the GetNodeVersionInfo response object and supporting the Access API endpoint.

Consider the following suggestions for future improvements:

  1. Add unit tests to ensure the connector behaves correctly with various API responses.
  2. If this connector is part of a larger set of API interactions, consider creating a base class or interface to standardize error handling and response processing across different API calls.
java-example/src/main/java/org/onflow/examples/java/getNodeVersionInfo/GetNodeVersionInfoAccessAPIConnector.java (2)

6-8: LGTM: Class structure is well-designed, with a minor naming suggestion.

The class structure is well-designed with proper encapsulation. The use of a final field for accessAPI promotes immutability, which is a good practice.

Consider renaming the class to NodeVersionInfoAccessApiConnector for better consistency with Java naming conventions (API should be capitalized in compound words).


13-21: LGTM with suggestions: getNodeVersionInfo method is functional but could be improved.

The method correctly handles both success and error cases. However, there are a few suggestions for improvement:

  1. Consider using a custom checked exception instead of RuntimeException for better error handling and documentation.
  2. Add a null check for the response to prevent potential NullPointerExceptions.
  3. Use pattern matching (if your Java version supports it) instead of instanceof for more concise code.

Here's a suggested refactoring:

public FlowNodeVersionInfo getNodeVersionInfo() throws NodeVersionInfoException {
    FlowAccessApi.AccessApiCallResponse<FlowNodeVersionInfo> response = accessAPI.getNodeVersionInfo();
    if (response == null) {
        throw new NodeVersionInfoException("Received null response from API");
    }
    if (response instanceof FlowAccessApi.AccessApiCallResponse.Success success) {
        return success.getData();
    } else if (response instanceof FlowAccessApi.AccessApiCallResponse.Error error) {
        throw new NodeVersionInfoException(error.getMessage(), error.getThrowable());
    } else {
        throw new NodeVersionInfoException("Unexpected response type: " + response.getClass().getName());
    }
}

public class NodeVersionInfoException extends Exception {
    public NodeVersionInfoException(String message) {
        super(message);
    }
    public NodeVersionInfoException(String message, Throwable cause) {
        super(message, cause);
    }
}

This refactoring includes a null check, uses pattern matching (if supported by your Java version), and introduces a custom checked exception for more explicit error handling.

kotlin-example/src/test/kotlin/org/onflow/examples/kotlin/getNodeVersionInfo/GetNodeVersionInfoAccessAPIConnectorTest.kt (2)

11-12: LGTM: Class declaration and annotation are appropriate.

The @FlowEmulatorProjectTest annotation correctly sets up the Flow emulator environment for testing. The class name follows the convention for test classes.

Consider adding a brief KDoc comment describing the purpose of this test class for better documentation.


23-31: LGTM with suggestions: Test method is well-structured but could be more comprehensive.

The test method effectively verifies the basic functionality of getNodeVersionInfo(). However, consider the following improvements:

  1. The current assertions check for zero values and null, which might not represent real-world scenarios. Consider using more realistic test data.
  2. Add tests for error scenarios, such as network failures or invalid responses.
  3. Consider parameterized tests to cover various input scenarios.

Here's an example of how you could enhance the test:

@ParameterizedTest
@MethodSource("nodeVersionInfoProvider")
fun `Can fetch node version info for various scenarios`(
    protocolVersion: Int,
    sporkRootBlockHeight: Int,
    nodeRootBlockHeight: Int,
    compatibleRange: FlowCompatibleRange?
) {
    // Mock the accessAPI to return specific values
    every { accessAPI.getNodeVersionInfo() } returns FlowNodeVersionInfo(
        protocolVersion,
        sporkRootBlockHeight,
        nodeRootBlockHeight,
        compatibleRange
    )

    val nodeVersionInfo = nodeVersionInfoConnector.getNodeVersionInfo()
    
    assertNotNull(nodeVersionInfo)
    assertEquals(protocolVersion, nodeVersionInfo.protocolVersion)
    assertEquals(sporkRootBlockHeight, nodeVersionInfo.sporkRootBlockHeight)
    assertEquals(nodeRootBlockHeight, nodeVersionInfo.nodeRootBlockHeight)
    assertEquals(compatibleRange, nodeVersionInfo.compatibleRange)
}

companion object {
    @JvmStatic
    fun nodeVersionInfoProvider() = Stream.of(
        Arguments.of(1, 100, 200, FlowCompatibleRange(1, 2)),
        Arguments.of(2, 300, 400, null),
        // Add more test cases as needed
    )
}

This approach allows testing multiple scenarios and provides more comprehensive coverage.

java-example/src/test/java/org/onflow/examples/java/getNodeVersionInfo/GetNodeVersionInfoAccessAPIConnectorTest.java (2)

12-13: LGTM: Class declaration and annotation are appropriate.

The class name and annotation are well-chosen. However, consider adding a brief Javadoc comment to describe the purpose of this test class.

You could add a comment like this:

/**
 * Test class for {@link GetNodeVersionInfoAccessAPIConnector}.
 * This class verifies the functionality of fetching node version information.
 */
@FlowEmulatorProjectTest(flowJsonLocation = "../flow/flow.json")
public class GetNodeVersionInfoAccessAPIConnectorTest {
    // ... existing code ...
}

22-30: LGTM: Test method is comprehensive, but consider adding more scenarios.

The canFetchNodeVersionInfo test method is well-structured and covers the basic functionality. However, consider the following suggestions:

  1. Add more test cases to cover different scenarios, such as non-zero values for version fields.
  2. Consider testing error cases, like network failures or unexpected responses.
  3. The current test assumes specific initial values (0 and null). Verify if these are the expected default values or if they should be different.

Here's an example of an additional test case you might consider:

@Test
public void handleNonZeroVersionInfo() {
    // Mock or set up a non-zero version info
    FlowNodeVersionInfo expectedInfo = new FlowNodeVersionInfo(
        1, // protocolVersion
        100, // sporkRootBlockHeight
        200, // nodeRootBlockHeight
        new FlowCompatibleRange(1, 2) // compatibleRange
    );
    
    // Assuming you can mock the accessAPI to return this expectedInfo
    // when getNodeVersionInfo is called
    
    FlowNodeVersionInfo actualInfo = nodeVersionInfoConnector.getNodeVersionInfo();
    
    assertEquals(expectedInfo.getProtocolVersion(), actualInfo.getProtocolVersion());
    assertEquals(expectedInfo.getSporkRootBlockHeight(), actualInfo.getSporkRootBlockHeight());
    assertEquals(expectedInfo.getNodeRootBlockHeight(), actualInfo.getNodeRootBlockHeight());
    assertNotNull(actualInfo.getCompatibleRange());
    assertEquals(expectedInfo.getCompatibleRange().getMinProtocolVersion(), 
                 actualInfo.getCompatibleRange().getMinProtocolVersion());
    assertEquals(expectedInfo.getCompatibleRange().getMaxProtocolVersion(), 
                 actualInfo.getCompatibleRange().getMaxProtocolVersion());
}

This additional test case would help ensure that the connector correctly handles non-zero and non-null values.

sdk/src/main/kotlin/org/onflow/flow/sdk/FlowAccessApi.kt (1)

60-61: LGTM! Consider adding a comment for clarity.

The new getNodeVersionInfo() method is a great addition that aligns well with the PR objectives. It follows the interface's existing patterns and naming conventions.

Consider adding a KDoc comment to describe the method's purpose and any potential exceptions. For example:

/**
 * Retrieves the version information of the node.
 *
 * @return An AccessApiCallResponse containing FlowNodeVersionInfo on success,
 *         or an error message if the operation fails.
 */
fun getNodeVersionInfo(): AccessApiCallResponse<FlowNodeVersionInfo>
sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowNodeVersionInfoTest.kt (2)

11-32: LGTM: Comprehensive builder test with a minor enhancement suggestion.

The test thoroughly verifies that the builder correctly reflects all properties of the original FlowNodeVersionInfo instance. Good use of assertArrayEquals for byte array comparison of sporkId.

Consider adding a test case with a non-null compatibleRange to ensure the builder handles this property correctly as well.


73-117: LGTM: Comprehensive test for FlowNodeVersionInfo equality and hashcode.

This test effectively verifies the equality and hashcode implementations of FlowNodeVersionInfo. It covers various scenarios, including byte array equality for sporkId and handling of null compatibleRange. The test ensures that equal objects have the same hashcode and unequal objects have different hashcodes, which is crucial for correct behavior in collections.

Consider adding a test case where all properties are the same except for compatibleRange, to ensure it's properly factored into equality and hashcode calculations.

sdk/src/intTest/org/onflow/flow/sdk/transaction/TransactionIntegrationTest.kt (1)

58-74: Update error message and consider relaxing assertions

The new test method looks good overall, but there are a few points to consider:

  1. The error message in the catch block doesn't match the operation being performed. It should be updated to reflect that you're retrieving node version info, not network parameters.

  2. The assertions for specific values (0 for various fields) might be too rigid for an integration test. Consider using more flexible assertions that check for non-null or non-negative values instead.

  3. There's no assertion for the semVer field of nodeVersionInfo. Consider adding one to ensure this field is also populated.

Here's a suggested improvement:

@Test
fun `Can get node version info`() {
    val nodeVersionInfo = try {
        handleResult(
            accessAPI.getNodeVersionInfo(),
            "Failed to get node version info"
        )
    } catch (e: Exception) {
        fail("Failed to retrieve node version info: ${e.message}")
    }

    assertThat(nodeVersionInfo).isNotNull()
    assertThat(nodeVersionInfo.protocolVersion).isNotNegative()
    assertThat(nodeVersionInfo.sporkRootBlockHeight).isNotNegative()
    assertThat(nodeVersionInfo.nodeRootBlockHeight).isNotNegative()
    assertThat(nodeVersionInfo.semVer).isNotEmpty()
    // Only assert compatibleRange is null if that's the expected behavior
    // assertThat(nodeVersionInfo.compatibleRange).isNull()
}

This suggestion relaxes the assertions to be more suitable for an integration test while still verifying that the method returns valid data.

sdk/src/main/kotlin/org/onflow/flow/sdk/impl/FlowAccessApiImpl.kt (1)

345-362: LGTM! Consider minor refactoring for improved readability.

The implementation of getNodeVersionInfo looks good and aligns with the PR objectives. It correctly processes the response and handles potential errors.

Consider extracting the creation of FlowNodeVersionInfo into a separate private method for improved readability. Here's a suggested refactoring:

 override fun getNodeVersionInfo(): FlowAccessApi.AccessApiCallResponse<FlowNodeVersionInfo> {
     return try {
         val ret = api.getNodeVersionInfo(
             Access.GetNodeVersionInfoRequest.newBuilder()
                 .build()
         )
-
-        val compatibleRange = if (ret.info.hasCompatibleRange()) {
-            FlowCompatibleRange(ret.info.compatibleRange.startHeight, ret.info.compatibleRange.endHeight)
-        } else {
-            null
-        }
-
-        FlowAccessApi.AccessApiCallResponse.Success(FlowNodeVersionInfo(ret.info.semver, ret.info.commit, ret.info.sporkId.toByteArray(), ret.info.protocolVersion, ret.info.sporkRootBlockHeight, ret.info.nodeRootBlockHeight, compatibleRange))
+        FlowAccessApi.AccessApiCallResponse.Success(createFlowNodeVersionInfo(ret.info))
     } catch (e: Exception) {
         FlowAccessApi.AccessApiCallResponse.Error("Failed to get node version info", e)
     }
 }
+
+private fun createFlowNodeVersionInfo(info: Access.NodeVersionInfo): FlowNodeVersionInfo {
+    val compatibleRange = if (info.hasCompatibleRange()) {
+        FlowCompatibleRange(info.compatibleRange.startHeight, info.compatibleRange.endHeight)
+    } else {
+        null
+    }
+    return FlowNodeVersionInfo(
+        info.semver,
+        info.commit,
+        info.sporkId.toByteArray(),
+        info.protocolVersion,
+        info.sporkRootBlockHeight,
+        info.nodeRootBlockHeight,
+        compatibleRange
+    )
+}

This refactoring improves readability by separating the response processing logic from the main method body.

sdk/src/test/kotlin/org/onflow/flow/sdk/impl/AsyncFlowAccessApiImplTest.kt (1)

332-368: LGTM! Consider adding more test scenarios.

The new test method for getNodeVersionInfo is well-structured and comprehensive. It effectively tests all fields of the NodeVersionInfo object and aligns with the PR objectives.

To further improve the test coverage, consider adding the following scenarios:

  1. Test when the compatibleRange is null.
  2. Test error scenarios (e.g., when the API call fails).

Here's an example of how you could test for a null compatibleRange:

@Test
fun `test getNodeVersionInfo with null compatibleRange`() {
    val mockNodeVersionInfo = Access.GetNodeVersionInfoResponse.newBuilder()
        .setInfo(
            NodeVersionInfoOuterClass.NodeVersionInfo.newBuilder()
                .setSemver("v0.0.1")
                .setCommit("123456")
                .setSporkId(ByteString.copyFromUtf8("sporkId"))
                .setProtocolVersion(5)
                .setSporkRootBlockHeight(1000)
                .setNodeRootBlockHeight(1001)
                // No compatibleRange set
                .build()
        ).build()

    `when`(api.getNodeVersionInfo(any())).thenReturn(setupFutureMock(mockNodeVersionInfo))

    val result = asyncFlowAccessApi.getNodeVersionInfo().get()

    assert(result is FlowAccessApi.AccessApiCallResponse.Success)
    result as FlowAccessApi.AccessApiCallResponse.Success
    val nodeVersionInfo = result.data

    assertEquals("v0.0.1", nodeVersionInfo.semver)
    assertEquals("123456", nodeVersionInfo.commit)
    assertArrayEquals("sporkId".toByteArray(), nodeVersionInfo.sporkId)
    assertEquals(5, nodeVersionInfo.protocolVersion)
    assertEquals(1000L, nodeVersionInfo.sporkRootBlockHeight)
    assertEquals(1001L, nodeVersionInfo.nodeRootBlockHeight)
    assertNull(nodeVersionInfo.compatibleRange)
}
sdk/src/test/kotlin/org/onflow/flow/sdk/impl/FlowAccessApiImplTest.kt (2)

12-12: Consider using specific imports for better code clarity.

While using wildcard imports (import org.junit.jupiter.api.Assertions.* and import org.onflow.protobuf.entities.*) can reduce clutter in test files, it may make it less clear which specific assertions or entities are being used. Consider importing only the necessary classes or functions for improved code readability and maintainability.

Also applies to: 19-19


336-370: LGTM! Consider extracting the mock response creation for improved readability.

The new test method Test getNodeVersionInfo is well-structured and comprehensive. It covers all fields of the NodeVersionInfo and CompatibleRange objects, and uses appropriate assertions to verify each field. The test follows the Arrange-Act-Assert pattern, which is a good practice.

To further improve readability, consider extracting the creation of the mock GetNodeVersionInfoResponse into a separate helper method. This would make the test method more concise and easier to understand at a glance.

Example:

private fun createMockNodeVersionInfoResponse(): Access.GetNodeVersionInfoResponse {
    return Access.GetNodeVersionInfoResponse.newBuilder()
        .setInfo(
            NodeVersionInfoOuterClass.NodeVersionInfo.newBuilder()
                .setSemver("v0.0.1")
                .setCommit("123456")
                .setSporkId(ByteString.copyFromUtf8("sporkId"))
                .setProtocolVersion(5)
                .setSporkRootBlockHeight(1000)
                .setNodeRootBlockHeight(1001)
                .setCompatibleRange(
                    NodeVersionInfoOuterClass.CompatibleRange.newBuilder()
                        .setStartHeight(100)
                        .setEndHeight(200)
                        .build()
                )
                .build()
        ).build()
}

Then, in the test method:

val mockNodeVersionInfo = createMockNodeVersionInfoResponse()

This change would make the test method more focused on its primary purpose of testing the getNodeVersionInfo function.

sdk/src/main/kotlin/org/onflow/flow/sdk/impl/AsyncFlowAccessApiImpl.kt (1)

517-541: LGTM! Consider extracting response mapping to a separate method.

The implementation of getNodeVersionInfo() is consistent with other methods in the class and correctly handles exceptions and response processing. Good job on handling the nullable compatibleRange.

To improve readability and maintainability, consider extracting the response mapping logic (lines 529-535) into a separate private method. This would make the main method more concise and easier to understand at a glance.

Here's a suggested refactor:

private fun mapToFlowNodeVersionInfo(info: Access.NodeVersionInfo): FlowNodeVersionInfo {
    val compatibleRange = if (info.hasCompatibleRange()) {
        FlowCompatibleRange(info.compatibleRange.startHeight, info.compatibleRange.endHeight)
    } else {
        null
    }
    return FlowNodeVersionInfo(
        info.semver,
        info.commit,
        info.sporkId.toByteArray(),
        info.protocolVersion,
        info.sporkRootBlockHeight,
        info.nodeRootBlockHeight,
        compatibleRange
    )
}

Then, in the getNodeVersionInfo() method, you can simplify the success case:

FlowAccessApi.AccessApiCallResponse.Success(mapToFlowNodeVersionInfo(response.info))

This refactoring would make the code more modular and easier to maintain.

sdk/src/main/kotlin/org/onflow/flow/sdk/models.kt (1)

1170-1230: LGTM: FlowNodeVersionInfo class is well-implemented with a minor suggestion.

The FlowNodeVersionInfo data class is comprehensively structured, covering all necessary aspects of node version information. The companion object, overridden equals() and hashCode() methods, and the builder method are all well-implemented.

Consider updating the builder method to handle the compatibleRange property:

 @JvmOverloads
 fun builder(builder: NodeVersionInfoOuterClass.NodeVersionInfo.Builder = NodeVersionInfoOuterClass.NodeVersionInfo.newBuilder()): NodeVersionInfoOuterClass.NodeVersionInfo.Builder = builder
     .setSemver(semver)
     .setCommit(commit)
     .setSporkId(UnsafeByteOperations.unsafeWrap(sporkId))
     .setProtocolVersion(protocolVersion)
     .setSporkRootBlockHeight(sporkRootBlockHeight)
     .setNodeRootBlockHeight(nodeRootBlockHeight)
+    .apply {
+        compatibleRange?.let {
+            setCompatibleRange(NodeVersionInfoOuterClass.NodeVersionInfo.CompatibleRange.newBuilder()
+                .setStartHeight(it.startHeight)
+                .setEndHeight(it.endHeight)
+            )
+        }
+    }

This change ensures that the compatibleRange is properly set in the builder when it's available.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 86b1d98 and f8afbfb.

📒 Files selected for processing (14)
  • java-example/src/main/java/org/onflow/examples/java/getNodeVersionInfo/GetNodeVersionInfoAccessAPIConnector.java (1 hunks)
  • java-example/src/test/java/org/onflow/examples/java/getNodeVersionInfo/GetNodeVersionInfoAccessAPIConnectorTest.java (1 hunks)
  • kotlin-example/src/main/kotlin/org/onflow/examples/kotlin/getNodeVersionInfo/GetNodeVersionInfoAccessAPIConnector.kt (1 hunks)
  • kotlin-example/src/test/kotlin/org/onflow/examples/kotlin/getNodeVersionInfo/GetNodeVersionInfoAccessAPIConnectorTest.kt (1 hunks)
  • sdk/build.gradle.kts (1 hunks)
  • sdk/src/intTest/org/onflow/flow/sdk/transaction/TransactionIntegrationTest.kt (1 hunks)
  • sdk/src/main/kotlin/org/onflow/flow/sdk/AsyncFlowAccessApi.kt (1 hunks)
  • sdk/src/main/kotlin/org/onflow/flow/sdk/FlowAccessApi.kt (1 hunks)
  • sdk/src/main/kotlin/org/onflow/flow/sdk/impl/AsyncFlowAccessApiImpl.kt (1 hunks)
  • sdk/src/main/kotlin/org/onflow/flow/sdk/impl/FlowAccessApiImpl.kt (1 hunks)
  • sdk/src/main/kotlin/org/onflow/flow/sdk/models.kt (1 hunks)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/impl/AsyncFlowAccessApiImplTest.kt (3 hunks)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/impl/FlowAccessApiImplTest.kt (2 hunks)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowNodeVersionInfoTest.kt (1 hunks)
🧰 Additional context used
🔇 Additional comments (17)
kotlin-example/src/main/kotlin/org/onflow/examples/kotlin/getNodeVersionInfo/GetNodeVersionInfoAccessAPIConnector.kt (2)

1-5: LGTM: Package declaration and imports are correct.

The package name follows Kotlin naming conventions, and the imports are relevant to the class functionality. No unused imports are present.


6-8: LGTM: Class definition is well-structured.

The GetNodeVersionInfoAccessAPIConnector class is correctly marked as internal and takes an appropriate parameter. The class name accurately describes its purpose.

java-example/src/main/java/org/onflow/examples/java/getNodeVersionInfo/GetNodeVersionInfoAccessAPIConnector.java (2)

1-5: LGTM: Package declaration and imports are appropriate.

The package declaration and imports are concise and relevant to the class functionality. Good job on keeping the imports minimal and focused.


9-11: LGTM: Constructor is well-implemented.

The constructor correctly initializes the final field and follows the dependency injection pattern. This design promotes testability and flexibility.

kotlin-example/src/test/kotlin/org/onflow/examples/kotlin/getNodeVersionInfo/GetNodeVersionInfoAccessAPIConnectorTest.kt (3)

3-9: LGTM: Imports are appropriate and concise.

The imports cover all necessary JUnit 5 and Flow SDK components required for this test class.


13-16: LGTM: Properties are well-defined and appropriately annotated.

The accessAPI property is correctly annotated with @FlowTestClient for automatic initialization. The nodeVersionInfoConnector is appropriately declared as private. Both use lateinit which is suitable for properties initialized in the setup method.


18-21: LGTM: Setup method is correctly implemented.

The setup method is properly annotated with @BeforeEach and initializes the nodeVersionInfoConnector with the accessAPI. This ensures a fresh instance for each test case.

java-example/src/test/java/org/onflow/examples/java/getNodeVersionInfo/GetNodeVersionInfoAccessAPIConnectorTest.java (3)

1-10: LGTM: Package and imports are well-organized.

The package declaration and imports are correctly structured. All necessary classes are imported, and there are no unused imports.


14-16: LGTM: Field declarations are appropriate.

The fields are correctly declared. The @FlowTestClient annotation on accessAPI suggests proper use of dependency injection for testing.


17-20: LGTM: Setup method is well-structured.

The setup method is correctly annotated with @BeforeEach and properly initializes the nodeVersionInfoConnector using the injected accessAPI.

sdk/src/main/kotlin/org/onflow/flow/sdk/AsyncFlowAccessApi.kt (1)

53-54: LGTM: New method aligns with PR objectives and interface design.

The addition of the getNodeVersionInfo() method to the AsyncFlowAccessApi interface is appropriate and aligns well with the PR objectives. It follows the existing pattern of returning a CompletableFuture<FlowAccessApi.AccessApiCallResponse<T>>, where T is the specific return type, in this case, FlowNodeVersionInfo.

This new method addresses the need to support the Access API endpoint for retrieving node version information, as outlined in the PR objectives and linked issues. It enhances the SDK's functionality by allowing clients to asynchronously fetch version details about the node.

A few points to consider:

  1. Ensure that the FlowNodeVersionInfo class is properly implemented to handle the protobuf objects mentioned in the PR summary.
  2. Update the documentation to include usage examples for this new method.
  3. Implement this method in the concrete classes that implement the AsyncFlowAccessApi interface.
  4. Add corresponding unit tests to verify the behavior of this new method.

To ensure that the FlowNodeVersionInfo class exists and is properly implemented, run the following script:

✅ Verification successful

LGTM: FlowNodeVersionInfo is properly defined and integrated.

The FlowNodeVersionInfo data class exists in sdk/src/main/kotlin/org/onflow/flow/sdk/models.kt and is appropriately utilized throughout the codebase. The newly added getNodeVersionInfo() method in the AsyncFlowAccessApi interface aligns with the existing design patterns and fulfills the PR objectives.

Next steps:

  1. Ensure that all implementations of the AsyncFlowAccessApi interface correctly override the getNodeVersionInfo() method.
  2. Confirm that corresponding unit tests effectively cover the new method's functionality.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the existence and implementation of FlowNodeVersionInfo class

# Test: Search for the FlowNodeVersionInfo class definition
ast-grep --lang kotlin --pattern 'class FlowNodeVersionInfo { $$$  }'

# Test: Check for any usage of FlowNodeVersionInfo in the codebase
rg --type kotlin 'FlowNodeVersionInfo'

Length of output: 3693


Script:

#!/bin/bash
# Description: Verify the existence and implementation of FlowNodeVersionInfo data class

# Test: Search for the FlowNodeVersionInfo data class definition
ast-grep --lang kotlin --pattern 'data class FlowNodeVersionInfo { $$$  }'

# Test: Check for any usage of FlowNodeVersionInfo in the codebase
rg --type kotlin 'FlowNodeVersionInfo'

Length of output: 3698


Script:

#!/bin/bash
# Description: Verify the existence and implementation of FlowNodeVersionInfo data class with constructor parameters

# Test: Search for the FlowNodeVersionInfo data class definition with constructor parameters
ast-grep --lang kotlin --pattern 'data class FlowNodeVersionInfo($_) { $$$ }'

# Test: Check for any usage of FlowNodeVersionInfo in the codebase
rg --type kotlin 'FlowNodeVersionInfo'

Length of output: 3701

sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowNodeVersionInfoTest.kt (4)

1-9: LGTM: Import statements are appropriate and concise.

The import statements cover all necessary classes for testing, including JUnit assertions, Protobuf utilities, and the SDK classes under test.


34-56: LGTM: Thorough test of the of method for Protobuf conversion.

This test effectively verifies the conversion from a Protobuf NodeVersionInfo to a FlowNodeVersionInfo instance. All properties are correctly asserted, including the null check for compatibleRange. The use of UnsafeByteOperations.unsafeWrap() for sporkId is appropriate for Protobuf handling.


58-71: LGTM: Well-structured test for FlowCompatibleRange equality and hashcode.

This test effectively verifies the equality and hashcode implementations of FlowCompatibleRange. It covers both positive (equal objects) and negative (unequal objects) cases, ensuring that equal objects have the same hashcode and unequal objects have different hashcodes. This is crucial for the correct behavior of these objects in collections.


1-117: Overall: Well-structured and comprehensive test suite.

This test file provides thorough coverage for the FlowNodeVersionInfo and FlowCompatibleRange classes. It effectively tests the builder pattern, static factory method, equality, and hashcode implementations. The tests are well-organized and cover various scenarios, including edge cases like null properties and byte array comparisons.

A few minor suggestions have been made to enhance the test coverage further, but overall, this is a solid set of unit tests that will help ensure the reliability and correctness of the SDK classes.

sdk/src/main/kotlin/org/onflow/flow/sdk/models.kt (2)

1165-1168: LGTM: FlowCompatibleRange class is well-defined.

The FlowCompatibleRange data class is correctly implemented with appropriate property types (Long) for block heights. The Serializable interface implementation is a good practice for data classes in this context.


1165-1230: Summary: New classes enhance SDK capabilities for handling node version information.

The addition of FlowCompatibleRange and FlowNodeVersionInfo classes expands the SDK's ability to work with node version details. These classes are well-integrated with the existing codebase, following established patterns and best practices. They provide a robust structure for handling version-related data, including compatibility ranges, which is crucial for managing blockchain node interactions.

The implementation is solid, with proper use of serialization, null safety, and conversion methods between SDK and protobuf objects. These additions will facilitate more detailed and accurate representation of node version information within the Flow SDK.

sdk/build.gradle.kts Show resolved Hide resolved
@franklywatson franklywatson self-requested a review October 15, 2024 18:21
#111, #113/ Updating models related to FlowBlock
#110/ CollectionGuarantee type differs from protobuf schema
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 10

🧹 Outside diff range and nitpick comments (27)
sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowQuorumCertificateTest.kt (4)

13-31: LGTM: test of() method is well-structured and comprehensive.

The test effectively verifies the of() method's functionality by mocking the gRPC object and asserting the correct mapping of properties.

Consider adding edge cases, such as testing with empty byte arrays or null values, to ensure robust error handling.


50-68: LGTM: test equals() method covers basic equality scenarios.

The test effectively verifies the equals() method for both equal and unequal FlowQuorumCertificate instances.

Consider enhancing the test with additional scenarios:

  1. Compare with null
  2. Compare with an object of a different type
  3. Test equality when only one property differs
    These additions would provide more comprehensive coverage of the equals() method.

70-88: LGTM: test hashCode() method covers basic hash code consistency.

The test effectively verifies that equal FlowQuorumCertificate instances have the same hash code, while different instances have different hash codes.

Consider enhancing the test with additional scenarios:

  1. Verify hash code consistency by calling hashCode() multiple times on the same object
  2. Test hash code behavior when only one property differs
    These additions would provide more robust coverage of the hashCode() method.

1-89: Overall structure of FlowQuorumCertificateTest is well-organized and comprehensive.

The test class provides good coverage of the FlowQuorumCertificate class, including its construction, equality comparison, and hash code generation. The use of descriptive test method names enhances readability.

Consider the following suggestions to further improve the test class:

  1. Add a @BeforeEach setup method to initialize common test data, reducing code duplication across test methods.
  2. Include tests for any public methods of FlowQuorumCertificate that are not currently covered (if any).
  3. Add tests for potential edge cases or error conditions to ensure robust error handling in the FlowQuorumCertificate class.
sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowExecutionReceiptMetaTest.kt (1)

73-91: LGTM with suggestion: Comprehensive test for hashCode() method

The test effectively verifies the hashCode() method of FlowExecutionReceiptMeta. It covers both positive and negative scenarios, ensuring that objects with the same properties have the same hash code and those with different properties have different hash codes.

Suggestion for improvement:
Consider adding a test case to verify the consistency between equals() and hashCode() methods. This ensures that if two objects are equal according to the equals() method, they must have the same hash code.

Here's an example of how you could add this test:

@Test
fun `test consistency between equals() and hashCode()`() {
    val meta1 = FlowExecutionReceiptMeta(executorId1, resultId1, spocks1, executorSignature1)
    val meta2 = FlowExecutionReceiptMeta(executorId1, resultId1, spocks1, executorSignature1)

    assertTrue(meta1 == meta2 && meta1.hashCode() == meta2.hashCode())
}
sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowTimeoutCertificateTest.kt (4)

45-81: LGTM: Well-structured test for the builder pattern.

The test thoroughly verifies the builder pattern implementation for FlowTimeoutCertificate. It covers all properties and ensures that the built object has the correct values. The use of ByteString.copyFrom() for byte array comparisons is a good practice.

Consider adding a test case for building a FlowTimeoutCertificate with null values for optional properties (if any) to ensure the builder handles such cases correctly.


83-104: LGTM: Good basic test for the equals() method.

The test covers the fundamental scenarios for equality testing of FlowTimeoutCertificate instances. It appropriately verifies that instances with identical properties are considered equal, while those with differing properties are not.

Consider enhancing the test with the following suggestions:

  1. Add a test case comparing a FlowTimeoutCertificate instance with null.
  2. Add a test case comparing a FlowTimeoutCertificate instance with an object of a different type.
  3. Test equality when only one property differs between two instances, for each property.
  4. If applicable, test with edge cases such as empty lists or byte arrays.

These additions would provide more comprehensive coverage of the equals() method implementation.


106-127: LGTM: Solid basic test for the hashCode() method.

The test effectively covers the fundamental scenarios for hash code testing of FlowTimeoutCertificate instances. It appropriately verifies that instances with identical properties have the same hash code, while those with differing properties have different hash codes.

Consider enhancing the test with the following suggestions:

  1. Add a test case to verify that if equals() returns true for two objects, their hash codes are also equal.
  2. Add test cases with edge cases such as empty lists or byte arrays.
  3. Verify that the hash code remains consistent across multiple invocations on the same object.
  4. If possible, test with a larger set of objects to ensure a good distribution of hash codes.

These additions would provide more comprehensive coverage of the hashCode() method implementation and its consistency with the equals() method.


1-128: Overall: Well-structured and comprehensive test suite for FlowTimeoutCertificate.

This test file provides a solid foundation for testing the FlowTimeoutCertificate class. It covers all major methods (of(), builder(), equals(), and hashCode()), uses appropriate mocking techniques, and includes meaningful assertions.

To further enhance the test suite, consider the following general improvements:

  1. Add more edge cases to each test method, especially for equals() and hashCode().
  2. Include tests for any potential exception scenarios.
  3. If there are any constraints or invariants for the FlowTimeoutCertificate class, add tests to verify they are maintained.
  4. Consider adding property-based tests using a library like jqwik to test with a wider range of inputs.
  5. If there are any complex interactions between FlowTimeoutCertificate and other classes, consider adding integration tests.

These enhancements would provide even more robust coverage and increase confidence in the FlowTimeoutCertificate implementation.

sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowChunkTest.kt (5)

13-49: LGTM! Consider adding a test for null input.

The test of() method is well-structured and thoroughly tests the conversion from ExecutionResultOuterClass.Chunk to FlowChunk. It covers all properties and uses appropriate assertions.

Consider adding a test case for null input to ensure the of() method handles it gracefully, either by throwing an appropriate exception or returning a default value.


51-89: LGTM! Consider testing the builder's setter methods.

The test builder() method effectively verifies that the builder() method creates a new instance with the same properties as the original FlowChunk. It covers all properties and uses appropriate assertions.

Consider expanding this test to verify the setter methods of the builder. This would ensure that each property can be individually modified:

@Test
fun `test builder() method`() {
    // ... existing test code ...

    val modifiedResult = flowChunk.builder()
        .setCollectionIndex(2)
        .setStartState(ByteString.copyFrom(ByteArray(32) { 0x07 }))
        // ... set other properties ...
        .build()

    assertEquals(2, modifiedResult.collectionIndex)
    assertEquals(ByteString.copyFrom(ByteArray(32) { 0x07 }), modifiedResult.startState)
    // ... assert other modified properties ...
}

This addition would provide more comprehensive coverage of the builder's functionality.


91-145: LGTM! Consider adding more granular equality tests.

The test equals() method effectively verifies the basic functionality of the equals() method for FlowChunk. It checks both equality and inequality cases.

To improve the test coverage, consider adding more granular tests that check equality when only one property differs at a time. This would help identify which specific property might cause equality to fail. For example:

@Test
fun `test equals() method`() {
    // ... existing test code ...

    // Test equality fails when only one property differs
    val flowChunk4 = flowChunk1.builder().setCollectionIndex(2).build()
    assertNotEquals(flowChunk1, flowChunk4)

    val flowChunk5 = flowChunk1.builder().setStartState(ByteString.copyFrom(ByteArray(32) { 0x07 })).build()
    assertNotEquals(flowChunk1, flowChunk5)

    // ... add similar tests for other properties ...
}

Also, consider adding tests for edge cases such as comparing with null or objects of different types:

assertNotEquals(flowChunk1, null)
assertNotEquals(flowChunk1, "Not a FlowChunk")

These additions would provide more comprehensive coverage of the equals() method's behavior.


147-202: LGTM! Consider adding more diverse hash code tests.

The test hashCode() method effectively verifies the basic functionality of the hashCode() method for FlowChunk. It checks that equal objects have the same hash code and unequal objects have different hash codes, which is crucial for the contract between equals() and hashCode().

To enhance the test coverage, consider the following improvements:

  1. Test consistency across multiple invocations:
assertEquals(flowChunk1.hashCode(), flowChunk1.hashCode())
  1. Test with more diverse objects:
val flowChunk4 = flowChunk1.builder().setCollectionIndex(2).build()
val flowChunk5 = flowChunk1.builder().setStartState(ByteString.copyFrom(ByteArray(32) { 0x07 })).build()
assertNotEquals(flowChunk1.hashCode(), flowChunk4.hashCode())
assertNotEquals(flowChunk1.hashCode(), flowChunk5.hashCode())
  1. Consider adding a test to verify that the hash code is reasonably distributed:
val hashCodes = mutableSetOf<Int>()
for (i in 1..100) {
    val flowChunk = FlowChunk(
        collectionIndex = i,
        startState = ByteArray(32) { (i % 256).toByte() },
        // ... set other properties ...
    )
    hashCodes.add(flowChunk.hashCode())
}
assertTrue(hashCodes.size > 95) // Expect most hash codes to be unique

These additions would provide more comprehensive coverage of the hashCode() method's behavior and distribution.


1-202: Great test coverage! Consider adding edge cases and parameterized tests.

The FlowChunkTest class provides good coverage of the main functionalities of the FlowChunk class. The tests are well-structured, readable, and use appropriate assertions and mocking techniques.

To further enhance the test suite, consider the following suggestions:

  1. Add edge case tests, such as empty byte arrays or extreme values for numeric fields.

  2. Implement parameterized tests for methods like of() and builder() to test with a variety of inputs:

@ParameterizedTest
@MethodSource("provideFlowChunkData")
fun `test of() method with various inputs`(
    collectionIndex: Int,
    startState: ByteArray,
    // ... other parameters ...
) {
    val grpcChunk = mock(ExecutionResultOuterClass.Chunk::class.java)
    // ... set up mock ...
    val flowChunk = FlowChunk.of(grpcChunk)
    // ... assertions ...
}

companion object {
    @JvmStatic
    fun provideFlowChunkData() = Stream.of(
        Arguments.of(1, ByteArray(32) { 0x01 }, /* ... */),
        Arguments.of(0, ByteArray(0), /* ... */),
        // ... more test cases ...
    )
}
  1. Consider adding tests for any exception cases, if applicable.

  2. If not already present elsewhere, add integration tests that verify the FlowChunk class works correctly with other components of the system.

These additions would make the test suite even more robust and comprehensive.

sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowExecutionResultTest.kt (6)

28-68: Consider adding more assertions for the chunks property

The test comprehensively covers the creation of FlowExecutionResult from ExecutionResultByIDResponse. To further enhance the test coverage, consider adding assertions for the properties of the chunks list item. This will ensure that all the chunk data is correctly transferred to the FlowExecutionResult object.

For example, you could add:

with(flowExecutionResult.chunks[0]) {
    assertEquals(collectionIndex, this.collectionIndex)
    assertArrayEquals(startStateBytes, this.startState)
    assertArrayEquals(eventCollectionBytes, this.eventCollection)
    assertEquals(FlowId.of(blockIdBytes), this.blockId)
    assertEquals(totalComputationUsed, this.totalComputationUsed)
    assertEquals(numberOfTransactions, this.numberOfTransactions)
    assertEquals(index, this.index)
    assertArrayEquals(endStateBytes, this.endState)
    assertEquals(FlowId.of(executionDataIdBytes), this.executionDataId)
    assertArrayEquals(stateDeltaCommitmentBytes, this.stateDeltaCommitment)
}

This addition will provide a more thorough verification of the FlowExecutionResult object's contents.


70-105: Consider adding more assertions for the chunks property

Similar to the previous test method, this test could benefit from additional assertions on the chunks property of the resulting FlowExecutionResult object. This will ensure that all the chunk data is correctly transferred when creating the object from an ExecutionResult.

You could add the same assertions as suggested for the previous test:

with(flowExecutionResult.chunks[0]) {
    assertEquals(collectionIndex, this.collectionIndex)
    assertArrayEquals(startStateBytes, this.startState)
    assertArrayEquals(eventCollectionBytes, this.eventCollection)
    assertEquals(FlowId.of(blockIdBytes), this.blockId)
    assertEquals(totalComputationUsed, this.totalComputationUsed)
    assertEquals(numberOfTransactions, this.numberOfTransactions)
    assertEquals(index, this.index)
    assertArrayEquals(endStateBytes, this.endState)
    assertEquals(FlowId.of(executionDataIdBytes), this.executionDataId)
    assertArrayEquals(stateDeltaCommitmentBytes, this.stateDeltaCommitment)
}

This addition will provide a more comprehensive verification of the FlowExecutionResult object's contents.


107-137: Enhance builder test with more detailed assertions

The test for the builder() method could be more comprehensive. Consider adding more detailed assertions to verify that all properties of the built object match the original FlowExecutionResult. This will ensure that the builder correctly transfers all data to the protobuf object.

You could add assertions like:

with(result.getChunks(0)) {
    assertEquals(flowChunk.collectionIndex, this.collectionIndex)
    assertEquals(ByteString.copyFrom(flowChunk.startState), this.startState)
    assertEquals(ByteString.copyFrom(flowChunk.eventCollection), this.eventCollection)
    assertEquals(flowChunk.blockId.byteStringValue, this.blockId)
    assertEquals(flowChunk.totalComputationUsed, this.totalComputationUsed)
    assertEquals(flowChunk.numberOfTransactions, this.numberOfTransactions)
    assertEquals(flowChunk.index, this.index)
    assertEquals(ByteString.copyFrom(flowChunk.endState), this.endState)
    assertEquals(flowChunk.executionDataId.byteStringValue, this.executionDataId)
    assertEquals(ByteString.copyFrom(flowChunk.stateDeltaCommitment), this.stateDeltaCommitment)
}

with(result.getServiceEvents(0)) {
    assertEquals(serviceEvent.type, this.type)
    assertEquals(ByteString.copyFrom(serviceEvent.payload), this.payload)
}

These additional assertions will provide a more thorough verification of the builder's functionality.


139-174: Enhance equals() test with more edge cases

The test for the equals() method covers the basic cases well. To make it more robust, consider adding the following test cases:

  1. Test equality with the same contents but different order of chunks and service events.
  2. Test equality with null values for optional fields (if any).
  3. Test equality with empty lists for chunks and service events.

For example, you could add:

// Test equality with different order of chunks and events
val flowExecutionResult4 = FlowExecutionResult(
    blockId = blockId1,
    previousResultId = previousResultId1,
    chunks = listOf(chunk1, mock(FlowChunk::class.java)),
    serviceEvents = listOf(serviceEvent1, mock(FlowServiceEvent::class.java))
)
val flowExecutionResult5 = FlowExecutionResult(
    blockId = blockId1,
    previousResultId = previousResultId1,
    chunks = listOf(mock(FlowChunk::class.java), chunk1),
    serviceEvents = listOf(mock(FlowServiceEvent::class.java), serviceEvent1)
)
assertEquals(flowExecutionResult4, flowExecutionResult5)

// Test equality with empty lists
val flowExecutionResult6 = FlowExecutionResult(
    blockId = blockId1,
    previousResultId = previousResultId1,
    chunks = emptyList(),
    serviceEvents = emptyList()
)
val flowExecutionResult7 = FlowExecutionResult(
    blockId = blockId1,
    previousResultId = previousResultId1,
    chunks = emptyList(),
    serviceEvents = emptyList()
)
assertEquals(flowExecutionResult6, flowExecutionResult7)

These additional test cases will help ensure that the equals() method handles various scenarios correctly.


176-211: Enhance hashCode() test with more edge cases

The test for the hashCode() method covers the basic cases well. To make it more comprehensive and align it with the suggested improvements for the equals() method, consider adding the following test cases:

  1. Test hash code consistency with different orders of chunks and service events.
  2. Test hash code with null values for optional fields (if any).
  3. Test hash code with empty lists for chunks and service events.

For example, you could add:

// Test hash code consistency with different order of chunks and events
val flowExecutionResult4 = FlowExecutionResult(
    blockId = blockId1,
    previousResultId = previousResultId1,
    chunks = listOf(chunk1, mock(FlowChunk::class.java)),
    serviceEvents = listOf(serviceEvent1, mock(FlowServiceEvent::class.java))
)
val flowExecutionResult5 = FlowExecutionResult(
    blockId = blockId1,
    previousResultId = previousResultId1,
    chunks = listOf(mock(FlowChunk::class.java), chunk1),
    serviceEvents = listOf(mock(FlowServiceEvent::class.java), serviceEvent1)
)
assertEquals(flowExecutionResult4.hashCode(), flowExecutionResult5.hashCode())

// Test hash code with empty lists
val flowExecutionResult6 = FlowExecutionResult(
    blockId = blockId1,
    previousResultId = previousResultId1,
    chunks = emptyList(),
    serviceEvents = emptyList()
)
val flowExecutionResult7 = FlowExecutionResult(
    blockId = blockId1,
    previousResultId = previousResultId1,
    chunks = emptyList(),
    serviceEvents = emptyList()
)
assertEquals(flowExecutionResult6.hashCode(), flowExecutionResult7.hashCode())

These additional test cases will help ensure that the hashCode() method is consistent with the equals() method and handles various scenarios correctly.


1-212: Overall good test coverage with room for improvement

The FlowExecutionResultTest class provides a solid foundation for testing the FlowExecutionResult class. It covers the main functionality including object creation, building, equality, and hash code generation. However, to further enhance the test suite, consider the following overall improvements:

  1. Add more detailed assertions for object properties, especially for nested objects like chunks and service events.
  2. Include more edge cases in the equality and hash code tests, such as different ordering of list elements and empty lists.
  3. If not already present in other test files, consider adding tests for error cases, such as invalid input data or edge cases that might cause exceptions.

These enhancements will contribute to a more robust and comprehensive test suite, increasing confidence in the FlowExecutionResult class's correctness and reliability.

sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowBlockHeaderTest.kt (3)

13-28: Consider improving test isolation for timeoutCertificate.

The companion object provides reusable test data, which is good for maintaining consistency across tests. However, the use of a static mock object for timeoutCertificate might lead to potential issues with test isolation.

Consider creating the mock FlowTimeoutCertificate within each test method that requires it, or use a @BeforeEach method to reset the mock before each test. This approach ensures that each test starts with a clean state and prevents potential interference between tests.

Example:

@BeforeEach
fun setup() {
    timeoutCertificate = mock(FlowTimeoutCertificate::class.java)
}

29-75: Enhance test coverage for test of() method.

The test thoroughly checks the conversion from a gRPC block header to a FlowBlockHeader and covers most properties of the FlowBlockHeader class. However, it could be improved by adding assertions for the lastViewTc property.

Consider adding assertions to verify the correct conversion of the lastViewTc property. This will ensure that the TimeoutCertificate is properly mapped from the gRPC object to the FlowBlockHeader instance.

Example:

assertNotNull(flowBlockHeader.lastViewTc)
assertEquals(timeoutCertificateMock.signerIndices.toByteArray(), flowBlockHeader.lastViewTc?.signerIndices)
assertEquals(timeoutCertificateMock.sigData.toByteArray(), flowBlockHeader.lastViewTc?.sigData)
// Add more assertions for other properties of lastViewTc

77-136: Enhance test coverage for test builder() method.

The test thoroughly checks the conversion from a FlowBlockHeader to a gRPC BlockHeader using the builder() method and covers most properties of the BlockHeader. However, it could be improved by adding assertions for the lastViewTc property of the built gRPC BlockHeader.

Consider adding assertions to verify the correct conversion of the lastViewTc property in the built gRPC BlockHeader. This will ensure that the TimeoutCertificate is properly mapped from the FlowBlockHeader instance to the gRPC object.

Example:

val builtLastViewTc = result.lastViewTc
assertNotNull(builtLastViewTc)
assertEquals(timeoutCertificate.view, builtLastViewTc.view)
assertEquals(UnsafeByteOperations.unsafeWrap(timeoutCertificate.signerIndices), builtLastViewTc.signerIndices)
assertEquals(UnsafeByteOperations.unsafeWrap(timeoutCertificate.sigData), builtLastViewTc.sigData)
// Add more assertions for other properties of lastViewTc
sdk/src/test/kotlin/org/onflow/flow/sdk/impl/AsyncFlowAccessApiImplTest.kt (1)

397-433: LGTM! Comprehensive test for getNodeVersionInfo.

The new test method test getNodeVersionInfo is well-structured and thoroughly covers all fields of the NodeVersionInfo object. It correctly asserts the values of the parsed result against the mock data, following the established pattern of other tests in this file.

A minor suggestion for improvement:

Consider using constants for the mock values (e.g., semver, commit, sporkId) to improve readability and make it easier to update these values if needed in the future. For example:

private companion object {
    const val MOCK_SEMVER = "v0.0.1"
    const val MOCK_COMMIT = "123456"
    const val MOCK_SPORK_ID = "sporkId"
    // ... other constants ...
}

Then use these constants in the test method.

sdk/src/test/kotlin/org/onflow/flow/sdk/impl/FlowAccessApiImplTest.kt (1)

355-389: Excellent addition of getNodeVersionInfo test.

The new test method thoroughly verifies the getNodeVersionInfo functionality:

  1. It properly mocks the API response.
  2. All fields of the returned FlowNodeVersionInfo object are verified.
  3. The test covers the happy path and correct parsing of the response.
  4. The use of assertResultSuccess ensures that the API call was successful before checking the result.

Consider adding an additional test case for the error scenario to ensure proper error handling. For example:

@Test
fun `Test getNodeVersionInfo error case`() {
    val exception = RuntimeException("Test exception")
    `when`(mockApi.getNodeVersionInfo(any())).thenThrow(exception)

    val result = flowAccessApiImpl.getNodeVersionInfo()

    assertTrue(result is FlowAccessApi.AccessApiCallResponse.Error)
    assertEquals("Test exception", (result as FlowAccessApi.AccessApiCallResponse.Error).message)
}
sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowBlockTest.kt (1)

54-57: Ensure All New Properties Are Properly Tested

You've added executionReceiptMetaList and executionResultList properties to the FlowBlock class and assert that they are empty. To maintain thorough test coverage, consider adding more detailed tests for these properties, especially if they can contain data in other scenarios.

sdk/src/main/kotlin/org/onflow/flow/sdk/models.kt (1)

317-323: Simplify the Event Filtering Logic

In the getEventsOfType method, the filtering logic can be simplified for better readability. Combining the conditions into a single expression improves clarity.

 .filter {
-    if (exact) {
-        it.type == type
-    } else {
-        it.type.endsWith(type)
-    }
+    (exact && it.type == type) || (!exact && it.type.endsWith(type))
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between f8afbfb and 3217387.

📒 Files selected for processing (11)
  • sdk/src/main/kotlin/org/onflow/flow/sdk/models.kt (16 hunks)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/impl/AsyncFlowAccessApiImplTest.kt (10 hunks)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/impl/FlowAccessApiImplTest.kt (9 hunks)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowBlockHeaderTest.kt (1 hunks)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowBlockTest.kt (4 hunks)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowChunkTest.kt (1 hunks)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowCollectionGuaranteeTest.kt (2 hunks)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowExecutionReceiptMetaTest.kt (1 hunks)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowExecutionResultTest.kt (1 hunks)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowQuorumCertificateTest.kt (1 hunks)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowTimeoutCertificateTest.kt (1 hunks)
🧰 Additional context used
🔇 Additional comments (23)
sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowCollectionGuaranteeTest.kt (5)

16-17: LGTM! Comprehensive test coverage for new fields.

The changes in this test method effectively cover the new fields (referenceBlockId, signature, and signerIndices) added to the FlowCollectionGuarantee class. The test now builds a CollectionGuarantee with these new fields and verifies them in the resulting FlowCollectionGuarantee object.

Also applies to: 20-20, 26-28, 36-38


44-45: LGTM! Proper test setup for new fields.

The test setup has been appropriately updated to include the new fields (referenceBlockId, signature, and signerIndices) required for the FlowCollectionGuarantee constructor. This ensures that the test covers all aspects of the updated class.

Also applies to: 47-47


58-60: LGTM! Comprehensive assertions for new fields.

The new assertions effectively verify that the referenceBlockId, signature, and signerIndices fields are correctly set in the resulting CollectionGuarantee object. This ensures that the conversion from FlowCollectionGuarantee to CollectionGuarantee is working as expected for all fields, including the newly added ones.


49-49: LGTM! Updated constructor call.

The FlowCollectionGuarantee constructor call has been correctly updated to include the new fields: referenceBlockId, signature, and signerIndices. This is consistent with the changes mentioned in the AI-generated summary.

To ensure this change is consistent across the codebase, please run the following command:

#!/bin/bash
# Search for other usages of FlowCollectionGuarantee constructor
rg --type kotlin "FlowCollectionGuarantee\(" -C 2

10-10: Verify the usage of UnsafeByteOperations.

The addition of UnsafeByteOperations import suggests performance optimization. While this can be beneficial, it's important to ensure its usage is necessary and safe in this context.

Please confirm that:

  1. The use of UnsafeByteOperations is required for performance reasons.
  2. The byte array passed to unsafeWrap is not modified after wrapping.
  3. The resulting ByteString is not used beyond the scope where the original byte array is valid.
✅ Verification successful

UnsafeByteOperations Usage Verified

The use of UnsafeByteOperations in FlowCollectionGuaranteeTest.kt is isolated to this test context. Please ensure that:

  1. The byte array passed to unsafeWrap remains unmodified after wrapping.
  2. The resulting ByteString is utilized solely within the scope where the original byte array is valid.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other usages of UnsafeByteOperations in the codebase
rg --type kotlin "UnsafeByteOperations" -C 3

Length of output: 1586

sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowQuorumCertificateTest.kt (2)

3-9: LGTM: Import statements are appropriate and concise.

The import statements cover all necessary classes for JUnit 5, Mockito, and the Flow SDK. There are no unused imports, which is good for code cleanliness.


33-48: LGTM: test builder() method effectively verifies the builder pattern.

This test comprehensively checks that the builder() method correctly preserves all properties of the FlowQuorumCertificate. It provides good coverage for both the constructor and the builder method.

sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowExecutionReceiptMetaTest.kt (4)

14-33: LGTM: Comprehensive test for of() method

The test thoroughly verifies the mapping from ExecutionReceiptMeta to FlowExecutionReceiptMeta. It covers all properties and uses appropriate assertions. The use of mock objects is well-implemented.


35-51: LGTM: Well-structured test for builder() method

The test effectively verifies the builder() method of FlowExecutionReceiptMeta. It covers all properties and ensures correct conversion to the protobuf representation. The assertions are appropriate and comprehensive.


53-71: LGTM: Thorough test for equals() method

The test effectively verifies the equals() method of FlowExecutionReceiptMeta. It covers both positive and negative equality scenarios, ensuring that objects with the same properties are considered equal and those with different properties are not. The assertions are appropriate and comprehensive.


1-92: Excellent test coverage and structure

The FlowExecutionReceiptMetaTest class provides comprehensive test coverage for the FlowExecutionReceiptMeta class. It effectively tests all main methods (of(), builder(), equals(), and hashCode()), using well-structured test methods with appropriate assertions. The use of mock objects and varied input data ensures good scenario coverage.

The test class follows good practices for unit testing in Kotlin and contributes significantly to the reliability of the FlowExecutionReceiptMeta implementation.

sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowTimeoutCertificateTest.kt (1)

13-43: LGTM: Comprehensive test for the of() method.

The test thoroughly covers all properties of the FlowTimeoutCertificate class and uses mocking appropriately to isolate the test from external dependencies. The assertions are meaningful and verify the correctness of the of() method.

sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowExecutionResultTest.kt (1)

1-212: LGTM: Well-structured test class

The overall structure of the FlowExecutionResultTest class is well-organized. The use of a companion object for constants promotes code reuse and maintainability across multiple test methods.

sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowBlockHeaderTest.kt (3)

1-12: LGTM: Package, imports, and class declaration are correct.

The package declaration, imports, and class declaration are appropriate for the FlowBlockHeaderTest class. All necessary dependencies are imported, including JUnit, Mockito, and protobuf classes.


138-247: LGTM: Comprehensive tests for equals() and hashCode() methods.

The tests for equals() and hashCode() methods are well-implemented and follow best practices. They cover both positive and negative cases, ensuring that the implementation of these methods is correct. The tests verify:

  1. Identical instances are considered equal and have the same hash code.
  2. Different instances are not considered equal and have different hash codes.

This comprehensive approach helps maintain the contract between equals() and hashCode(), which is crucial for the correct behavior of FlowBlockHeader objects in collections.


1-247: Overall, well-structured and comprehensive test suite for FlowBlockHeader.

The FlowBlockHeaderTest class provides a thorough test suite for the FlowBlockHeader class. It covers the main functionality, including the of(), builder(), equals(), and hashCode() methods. The tests are well-structured and follow good testing practices.

A few minor improvements were suggested:

  1. Enhancing test isolation for the timeoutCertificate mock object.
  2. Adding assertions for the lastViewTc property in both of() and builder() tests.

These suggestions, if implemented, would further improve the already solid test coverage. Great job on creating a comprehensive test suite!

sdk/src/test/kotlin/org/onflow/flow/sdk/impl/AsyncFlowAccessApiImplTest.kt (2)

33-60: LGTM! Good addition of constants and mock object.

The introduction of the HEIGHT constant and the comprehensive mockBlockHeader object enhances the test suite's readability and maintainability. The mockBlockHeader is well-structured and includes all necessary fields, which will be useful for multiple tests.


80-80: LGTM! Consistent use of mockBlockHeader across tests.

The updates to use the mockBlockHeader in multiple test methods improve consistency and reduce code duplication. This change enhances the maintainability of the test suite without altering the core logic of the tests.

Also applies to: 92-93, 105-106, 118-130, 142-155, 167-180

sdk/src/test/kotlin/org/onflow/flow/sdk/impl/FlowAccessApiImplTest.kt (2)

12-12: LGTM: Import statements have been cleaned up.

The import statements have been simplified by consolidating imports from org.onflow.protobuf.entities and modifying the Assertions import. These changes improve code readability without introducing any issues.

Also applies to: 19-19


38-57: Great refactoring: Centralized mock object creation.

The addition of a companion object with mockBlockHeader and mockBlock properties is an excellent refactoring. This change:

  1. Centralizes the creation of mock objects used across multiple test methods.
  2. Reduces code duplication.
  3. Improves maintainability by providing a single point of modification for these mock objects.

The properties are properly initialized with all necessary fields, ensuring consistency across tests.

sdk/src/main/kotlin/org/onflow/flow/sdk/models.kt (3)

254-254: ⚠️ Potential issue

Fix the Nullable Type in Getter Method

In the FlowEvent class, the _jsonCadence variable is initialized as null, and the jsonCadence getter method does not handle the possibility of _jsonCadence being null during assignment. To prevent potential NullPointerException, consider using the safe call operator ?. or ensure that _jsonCadence is properly initialized.

     private var _jsonCadence: Field<*>? = null
     val jsonCadence: Field<*>
         get() {
-            if (_jsonCadence == null) {
+            if (_jsonCadence == null) {
                 _jsonCadence = Flow.decodeJsonCadence(bytes)
             }
             return _jsonCadence!!
         }

Likely invalid or redundant comment.


Line range hint 632-715: Ensure Consistency in FlowBlockHeader Equality and HashCode Methods

The equals and hashCode methods for FlowBlockHeader should include all properties for accurate comparisons. Verify that properties like payloadHash, parentVoterSigData, proposerSigData, and parentVoterIndices are correctly compared using contentEquals for byte arrays.

To confirm, run the following script to check the equality methods:


1167-1170: Check for Missing Signatures in FlowCollectionGuarantee

In the FlowCollectionGuarantee.of method, ensure that all necessary signatures are included, especially if the reference block ID and signature fields are critical for validation.

sdk/src/main/kotlin/org/onflow/flow/sdk/models.kt Outdated Show resolved Hide resolved
sdk/src/main/kotlin/org/onflow/flow/sdk/models.kt Outdated Show resolved Hide resolved
@@ -608,6 +618,7 @@
signature = FlowSignature(value.signature.toByteArray())
)
}

Copy link
Contributor

@coderabbitai coderabbitai bot Oct 16, 2024

Choose a reason for hiding this comment

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

⚠️ Potential issue

Correct the Key Assignment in FlowTransactionSignature.of

In the of method for FlowTransactionSignature, signerIndex and keyIndex are both assigned value.keyId, which might be incorrect. Verify that signerIndex should be assigned differently, possibly from a different field in value.

 FlowTransactionSignature(
     address = FlowAddress.of(value.address.toByteArray()),
-    signerIndex = value.keyId,
     keyIndex = value.keyId,
+    signerIndex = /* assign correct value here */
     signature = FlowSignature(value.signature.toByteArray())
 )

Committable suggestion was skipped due to low confidence.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

signerIndex does not seem to exist anymore in the protbuf files. Will open up a separate issue for this one to investigate if this field can be removed @franklywatson

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

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

🧹 Outside diff range and nitpick comments (11)
sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowCollectionGuaranteeTest.kt (2)

16-39: LGTM! Consider using constants for magic numbers.

The changes appropriately test the new fields added to the FlowCollectionGuarantee class. The test coverage has been expanded to include referenceBlockId, signature, and signerIndices.

Consider defining constants for the magic numbers used in the byte arrays (e.g., 1, 2, 3, 10, 11, 12, etc.) to improve readability and maintainability. For example:

private companion object {
    val COLLECTION_ID_BYTES = byteArrayOf(1, 2, 3)
    val REFERENCE_BLOCK_ID_BYTES = byteArrayOf(10, 11, 12)
    // ... other constants
}

59-61: LGTM! Consider adding null checks.

The new assertions correctly verify the referenceBlockId, signature, and signerIndices fields in the built CollectionGuarantee object. This ensures comprehensive test coverage for all new fields.

Consider adding null checks for the new fields before asserting their values. This can help catch potential issues where these fields might be unexpectedly null. For example:

assertEquals(ByteString.copyFrom(referenceBlockId.bytes), collectionGuarantee.referenceBlockId)
assertNotNull(collectionGuarantee.signature, "Signature should not be null")
assertEquals(ByteString.copyFrom(signature.bytes), collectionGuarantee.signature)
assertNotNull(collectionGuarantee.signerIndices, "Signer indices should not be null")
assertEquals(ByteString.copyFrom(signerIndices), collectionGuarantee.signerIndices)
sdk/src/main/kotlin/org/onflow/flow/sdk/FlowAccessApi.kt (1)

65-66: LGTM! Consider adding KDoc for consistency.

The new getNodeVersionInfo() method is a great addition to the FlowAccessApi interface. It follows the established pattern of other methods and uses the appropriate return type.

For consistency with other methods in this interface, consider adding KDoc to briefly describe the method's purpose and return value. For example:

/**
 * Retrieves version information for the node.
 *
 * @return An [AccessApiCallResponse] containing [FlowNodeVersionInfo] on success.
 */
fun getNodeVersionInfo(): AccessApiCallResponse<FlowNodeVersionInfo>
sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowNodeVersionInfoTest.kt (4)

34-57: LGTM: Thorough test for FlowNodeVersionInfo.of method

The test effectively verifies the conversion from a protobuf NodeVersionInfo object to a FlowNodeVersionInfo instance. All properties are checked, including a null check for compatibleRange.

Consider adding a comment explaining the use of UnsafeByteOperations.unsafeWrap for sporkId in the protobuf builder, as it might not be immediately clear why this unsafe operation is necessary.


59-72: LGTM: Well-structured test for FlowCompatibleRange equality and hashcode

The test effectively verifies the equality and hashcode implementations of FlowCompatibleRange. It covers both positive and negative cases for equality and ensures hashcode consistency.

Consider adding tests for edge cases, such as:

  1. Ranges with the same start height but different end heights.
  2. Ranges with the same end height but different start heights.
  3. A range compared with null or a different object type.

These additional cases would provide more comprehensive coverage of the equality implementation.


74-117: LGTM: Comprehensive test for FlowNodeVersionInfo equality and hashcode

The test effectively verifies the equality and hashcode implementations of FlowNodeVersionInfo. It covers both positive and negative cases for equality, ensures hashcode consistency, and includes a case with a null compatibleRange.

To further enhance the test coverage, consider adding the following cases:

  1. Two FlowNodeVersionInfo instances that differ only in one property (e.g., only semver is different).
  2. Comparison with null or a different object type.
  3. A case where all properties are the same except for sporkId, which has the same content but is a different instance.

These additional cases would provide more comprehensive coverage of the equality implementation and edge cases.


1-118: Overall: Well-implemented test suite for FlowNodeVersionInfo and FlowCompatibleRange

This test file provides comprehensive coverage for the FlowNodeVersionInfo and FlowCompatibleRange classes. The tests are well-structured and cover important aspects such as the builder pattern, static factory method, equality, and hashcode implementations.

To further improve the test suite:

  1. Consider grouping related tests using nested classes or @Nested annotations for better organization.
  2. Add parameterized tests for edge cases to reduce code duplication and increase test coverage.
  3. Implement property-based testing for more exhaustive coverage of possible inputs.

These improvements would enhance the maintainability and thoroughness of the test suite.

sdk/src/main/kotlin/org/onflow/flow/sdk/impl/FlowAccessApiImpl.kt (1)

344-361: LGTM with a minor suggestion for improved error handling.

The implementation of getNodeVersionInfo looks good and follows the established pattern in the class. It correctly processes the response and handles the optional compatibleRange.

Consider enhancing the error message to include more details about the failure, similar to how it's done in some other methods of this class. For example:

FlowAccessApi.AccessApiCallResponse.Error("Failed to get node version info", e)

This would provide more context for debugging purposes.

sdk/src/test/kotlin/org/onflow/flow/sdk/impl/AsyncFlowAccessApiImplTest.kt (1)

465-503: Excellent addition of the getNodeVersionInfo test!

The new test method is comprehensive and well-structured, covering all relevant properties of the NodeVersionInfo, including the nested CompatibleRange. The assertions are thorough and use the appropriate methods for different data types.

A minor suggestion for improved readability:

Consider grouping related assertions together and adding comments to separate different sections of the test. For example:

// Assert main NodeVersionInfo properties
assertEquals("v0.0.1", nodeVersionInfo.semver)
assertEquals("123456", nodeVersionInfo.commit)
assertArrayEquals("sporkId".toByteArray(), nodeVersionInfo.sporkId)
assertEquals(5, nodeVersionInfo.protocolVersion)

// Assert block heights
assertEquals(1000L, nodeVersionInfo.sporkRootBlockHeight)
assertEquals(1001L, nodeVersionInfo.nodeRootBlockHeight)

// Assert CompatibleRange properties
assertEquals(100L, nodeVersionInfo.compatibleRange?.startHeight)
assertEquals(200L, nodeVersionInfo.compatibleRange?.endHeight)

This grouping can make the test more readable and easier to maintain in the future.

sdk/src/main/kotlin/org/onflow/flow/sdk/models.kt (2)

898-911: Override equals and hashCode in FlowExecutionReceiptMeta

The FlowExecutionReceiptMeta data class does not override equals and hashCode. If instances are used in collections or comparisons, it's important to ensure these methods are properly implemented.

Consider adding the following implementations:

override fun equals(other: Any?): Boolean {
    if (this === other) return true
    if (other !is FlowExecutionReceiptMeta) return false

    if (executorId != other.executorId) return false
    if (resultId != other.resultId) return false
    if (spocks != other.spocks) return false
    if (executorSignature != other.executorSignature) return false

    return true
}

override fun hashCode(): Int {
    var result = executorId.hashCode()
    result = 31 * result + resultId.hashCode()
    result = 31 * result + spocks.hashCode()
    result = 31 * result + executorSignature.hashCode()
    return result
}

Line range hint 1498-1502: Correct Typographical Error in Constructor Parameter

There's a typo in the constructor parameter name jasonCadence. It should be jsonCadence.

Apply this diff to fix the typo:

 data class FlowEventPayload(
     override val bytes: ByteArray
 ) : Serializable,
     BytesHolder {
-    constructor(jasonCadence: Field<*>) : this(Flow.encodeJsonCadence(jasonCadence))
+    constructor(jsonCadence: Field<*>) : this(Flow.encodeJsonCadence(jsonCadence))
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 3217387 and b6cc5ed.

⛔ Files ignored due to path filters (4)
  • .kotlin/errors/errors-1728577446477.log is excluded by !**/*.log
  • .kotlin/errors/errors-1728582141255.log is excluded by !**/*.log
  • .kotlin/errors/errors-1728834048981.log is excluded by !**/*.log
  • .kotlin/errors/errors-1728837866707.log is excluded by !**/*.log
📒 Files selected for processing (12)
  • kotlin-example/src/main/kotlin/org/onflow/examples/kotlin/getNodeVersionInfo/GetNodeVersionInfoAccessAPIConnector.kt (1 hunks)
  • sdk/build.gradle.kts (1 hunks)
  • sdk/src/main/kotlin/org/onflow/flow/sdk/FlowAccessApi.kt (1 hunks)
  • sdk/src/main/kotlin/org/onflow/flow/sdk/impl/AsyncFlowAccessApiImpl.kt (1 hunks)
  • sdk/src/main/kotlin/org/onflow/flow/sdk/impl/FlowAccessApiImpl.kt (1 hunks)
  • sdk/src/main/kotlin/org/onflow/flow/sdk/models.kt (13 hunks)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/impl/AsyncFlowAccessApiImplTest.kt (10 hunks)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/impl/FlowAccessApiImplTest.kt (9 hunks)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowBlockHeaderTest.kt (1 hunks)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowBlockTest.kt (4 hunks)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowCollectionGuaranteeTest.kt (2 hunks)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowNodeVersionInfoTest.kt (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • sdk/src/test/kotlin/org/onflow/flow/sdk/impl/FlowAccessApiImplTest.kt
  • sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowBlockHeaderTest.kt
  • sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowBlockTest.kt
🧰 Additional context used
🔇 Additional comments (13)
kotlin-example/src/main/kotlin/org/onflow/examples/kotlin/getNodeVersionInfo/GetNodeVersionInfoAccessAPIConnector.kt (3)

1-5: LGTM: Package declaration and imports are appropriate.

The package name follows Kotlin naming conventions, and the imports are relevant to the class functionality.


6-8: LGTM: Class declaration and constructor are well-defined.

The internal visibility modifier is appropriate for this utility class, and the constructor parameter is correctly marked as private and immutable.


1-14: Overall, well-implemented and follows Kotlin best practices.

The GetNodeVersionInfoAccessAPIConnector class is well-structured and serves its purpose effectively. It encapsulates the logic for retrieving node version information and handles both success and error cases appropriately. The code is concise and follows Kotlin best practices.

Consider implementing the suggested custom exception for more explicit error handling. This would further improve the already solid implementation.

sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowCollectionGuaranteeTest.kt (2)

10-10: Verify the necessity of using unsafe byte operations.

The addition of import com.google.protobuf.UnsafeByteOperations introduces the use of unsafe operations. While this can provide performance benefits, it may also lead to potential issues if not used carefully.

Could you please confirm if using UnsafeByteOperations is necessary here? If so, ensure that proper safeguards are in place to prevent any potential issues.


45-50: LGTM! Constructor updated correctly.

The FlowCollectionGuarantee constructor has been properly updated to include the new fields: referenceBlockId, signature, and signerIndices. This change ensures that the test covers the creation of a FlowCollectionGuarantee object with all the new fields.

sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowNodeVersionInfoTest.kt (1)

12-32: LGTM: Comprehensive test for FlowNodeVersionInfo builder

The test thoroughly checks all properties of the FlowNodeVersionInfo class using its builder. The assertions are well-structured and cover each property individually, including the correct use of assertArrayEquals for the sporkId byte array.

sdk/build.gradle.kts (1)

35-35: LGTM! Ensure compatibility and address build issues.

The update of the org.onflow:flow dependency from 1.0.0 to 1.1.0 aligns with the PR objectives to enhance the JVM SDK functionality. This minor version update should introduce new features or bug fixes while maintaining backward compatibility.

To ensure a smooth integration:

  1. Review the changelog of the org.onflow:flow library for version 1.1.0 to understand the changes and new features.
  2. Update the project's documentation to reflect this dependency update and any new features it enables.
  3. Run the entire test suite to verify that the update doesn't introduce any regressions.

Additionally, please address the build and test issues mentioned in the previous review:

  • Ensure that JAVA_HOME is correctly set in the environment.
  • Verify that all instances of the org.onflow:flow dependency version have been updated to 1.1.0 throughout the codebase.

To verify the update and address the previous issues, please run the following script:

sdk/src/test/kotlin/org/onflow/flow/sdk/impl/AsyncFlowAccessApiImplTest.kt (3)

33-60: LGTM! Good additions for improved testing.

The new HEIGHT constant and mockBlockHeader are well-structured and comprehensive. They will enhance the readability and maintainability of the test code. The mockBlockHeader includes all necessary properties, which will be useful for thorough testing of block header-related functionality.


Line range hint 80-195: Great refactoring to improve test consistency!

The updates to use the new mockBlockHeader in multiple test methods (getLatestBlockHeader, getBlockHeaderById, getBlockHeaderByHeight, getLatestBlock, getBlockById, getBlockByHeight) significantly improve the consistency and reduce duplication in the test code. This refactoring enhances the maintainability of the tests and ensures that all block header-related tests use the same mock data.


Line range hint 1-654: Overall, excellent improvements to the AsyncFlowAccessApiImplTest!

The changes in this file significantly enhance the quality and consistency of the test suite:

  1. The introduction of the HEIGHT constant and mockBlockHeader improves code reusability and maintainability.
  2. Refactoring existing tests to use the mockBlockHeader reduces duplication and ensures consistency across block header-related tests.
  3. The new getNodeVersionInfo test method provides comprehensive coverage for the new functionality.

These improvements will make the test suite more robust and easier to maintain in the future. Great job on enhancing the test code quality!

sdk/src/main/kotlin/org/onflow/flow/sdk/impl/AsyncFlowAccessApiImpl.kt (3)

591-615: LGTM! The new getNodeVersionInfo() method is well-implemented.

The implementation of getNodeVersionInfo() is consistent with other methods in the class and follows best practices:

  1. It uses the completableFuture wrapper for asynchronous execution.
  2. Proper error handling is in place, both for API call failures and general exceptions.
  3. The response is correctly mapped to the FlowNodeVersionInfo data class.
  4. The method handles the optional compatibleRange field appropriately.

591-615: The getNodeVersionInfo() method is consistent with the class design.

The implementation of getNodeVersionInfo() follows the established patterns in the AsyncFlowAccessApiImpl class:

  1. It uses the completableFuture wrapper for asynchronous execution.
  2. Error handling is consistent with other methods.
  3. The response is mapped to a domain-specific object (FlowNodeVersionInfo).
  4. The method signature matches the interface declaration.

This consistency contributes to the maintainability and readability of the codebase.


591-615: Summary: The addition of getNodeVersionInfo() is a well-implemented and non-disruptive change.

The new getNodeVersionInfo() method:

  1. Extends the functionality of the AsyncFlowAccessApiImpl class.
  2. Is consistent with the existing code style and patterns.
  3. Handles errors appropriately.
  4. Does not introduce any breaking changes to the existing codebase.

Overall, this is a clean and valuable addition to the class.

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

🧹 Outside diff range and nitpick comments (8)
sdk/src/main/kotlin/org/onflow/flow/sdk/models.kt (8)

Line range hint 630-713: LGTM! Consider adding documentation for new properties.

The changes to the FlowBlockHeader class look good. The new properties and their corresponding updates in the of and builder methods are well-implemented and consistent. The addition of custom equals and hashCode methods is a good practice for data classes with mutable properties like byte arrays.

Consider adding KDoc comments for the new properties to improve code documentation and maintainability.


Line range hint 724-758: LGTM! Consider updating equals and hashCode methods.

The changes to the FlowBlock class are well-implemented and consistent with the updates to the FlowBlockHeader class. The new properties and their corresponding updates in the of and builder methods look good.

Consider updating the equals and hashCode methods for the FlowBlock class to include the new properties, similar to what was done for FlowBlockHeader. This ensures proper equality checks and hashing behavior for the updated class.


897-918: LGTM! Consider adding documentation for the new class.

The addition of the FlowExecutionReceiptMeta data class is a good improvement, providing a structured way to represent execution receipt metadata. The of companion object method and builder method are well-implemented and consistent with other classes in the file.

Consider adding KDoc comments for the FlowExecutionReceiptMeta class and its properties to improve code documentation and maintainability.


920-966: LGTM! Consider adding documentation for the new class.

The addition of the FlowTimeoutCertificate data class is a good improvement, providing a structured way to represent timeout certificates. The of companion object method, builder method, and custom equals and hashCode methods are well-implemented and consistent with other classes in the file.

Consider adding KDoc comments for the FlowTimeoutCertificate class and its properties to improve code documentation and maintainability.


968-1007: LGTM! Consider adding documentation for the new class.

The addition of the FlowQuorumCertificate data class is a good improvement, providing a structured way to represent quorum certificates. The of companion object method, builder method, and custom equals and hashCode methods are well-implemented and consistent with other classes in the file.

Consider adding KDoc comments for the FlowQuorumCertificate class and its properties to improve code documentation and maintainability.


1156-1200: LGTM! Consider updating class documentation.

The changes to the FlowCollectionGuarantee class are well-implemented and consistent with the updates to other classes. The new properties and their corresponding updates in the of and builder methods look good. The addition of custom equals and hashCode methods is a good practice for data classes with mutable properties like byte arrays.

Consider updating the class-level documentation for FlowCollectionGuarantee to reflect the new properties and their purpose in the collection guarantee representation.


1431-1434: LGTM! Consider adding validation and documentation.

The addition of the FlowCompatibleRange data class is a good improvement, providing a clear structure for representing compatible block height ranges.

Consider the following improvements:

  1. Add KDoc comments to explain the purpose and usage of this class.
  2. Implement a custom constructor with validation to ensure that startHeight is less than or equal to endHeight.

Example:

/**
 * Represents a range of compatible block heights.
 *
 * @property startHeight The starting block height of the compatible range.
 * @property endHeight The ending block height of the compatible range.
 */
data class FlowCompatibleRange(
    val startHeight: Long,
    val endHeight: Long
) : Serializable {
    init {
        require(startHeight <= endHeight) { "startHeight must be less than or equal to endHeight" }
    }
}

1436-1504: LGTM! Consider adding documentation and improving null handling.

The addition of the FlowNodeVersionInfo data class is a valuable improvement, providing a structured way to represent detailed version information for Flow nodes. The of companion object method, builder method, and custom equals and hashCode methods are well-implemented and consistent with other classes in the file.

Consider the following improvements:

  1. Add KDoc comments for the class and its properties to improve code documentation.
  2. In the hashCode method, handle the case where compatibleRange is null to avoid potential NullPointerException.

Example for the hashCode method improvement:

override fun hashCode(): Int {
    var result = semver.hashCode()
    result = 31 * result + commit.hashCode()
    result = 31 * result + sporkId.contentHashCode()
    result = 31 * result + protocolVersion.hashCode()
    result = 31 * result + sporkRootBlockHeight.hashCode()
    result = 31 * result + nodeRootBlockHeight.hashCode()
    result = 31 * result + (compatibleRange?.hashCode() ?: 0)
    return result
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between b6cc5ed and 332ed19.

📒 Files selected for processing (1)
  • sdk/src/main/kotlin/org/onflow/flow/sdk/models.kt (14 hunks)
🧰 Additional context used
🔇 Additional comments (3)
sdk/src/main/kotlin/org/onflow/flow/sdk/models.kt (3)

788-800: LGTM! Builder method addition is consistent.

The addition of the builder method to the FlowChunk class is a good improvement. It follows the pattern used in other classes and provides a convenient way to create protobuf messages from FlowChunk instances.


845-849: LGTM! Builder method addition is consistent.

The addition of the builder method to the FlowServiceEvent class is a good improvement. It follows the pattern used in other classes and provides a convenient way to create protobuf messages from FlowServiceEvent instances.


880-895: LGTM! New methods enhance flexibility.

The additions to the FlowExecutionResult class are well-implemented:

  1. The new of method overload allows creating instances from ExecutionResultOuterClass.ExecutionResult, enhancing flexibility.
  2. The builder method addition is consistent with other classes and provides a convenient way to create protobuf messages.

These changes improve the usability and consistency of the FlowExecutionResult class.

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

🧹 Outside diff range and nitpick comments (2)
sdk/src/main/kotlin/org/onflow/flow/sdk/models.kt (2)

Line range hint 724-742: Consider Nullability in FlowBlock Fields

Properties like blockHeader and protocolStateId in FlowBlock might be null if not set in the protobuf. To prevent potential NullPointerException, handle their nullability appropriately.

Update the data class properties:

-    val blockHeader: FlowBlockHeader,
-    val protocolStateId: FlowId
+    val blockHeader: FlowBlockHeader?,
+    val protocolStateId: FlowId?

Modify the of method:

-    blockHeader = FlowBlockHeader.of(value.blockHeader),
-    protocolStateId = FlowId.of(value.protocolStateId.toByteArray())
+    blockHeader = if (value.hasBlockHeader()) FlowBlockHeader.of(value.blockHeader) else null,
+    protocolStateId = if (value.protocolStateId.isEmpty) null else FlowId.of(value.protocolStateId.toByteArray())

Adjust the builder method:

-    .setBlockHeader(blockHeader.builder().build())
-    .setProtocolStateId(protocolStateId.byteStringValue)
+    blockHeader?.let { builder.setBlockHeader(it.builder().build()) }
+    protocolStateId?.let { builder.setProtocolStateId(it.byteStringValue) }

897-902: Nitpick: Remove Unnecessary Trailing Comma

The trailing comma after the last parameter in FlowExecutionReceiptMeta can be removed for cleaner code.

Apply this diff:

 data class FlowExecutionReceiptMeta(
     val executorId: FlowId,
     val resultId: FlowId,
     val spocks: List<ByteArray>,
-    val executorSignature: FlowSignature,
+    val executorSignature: FlowSignature
 )
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 332ed19 and fc88f83.

📒 Files selected for processing (1)
  • sdk/src/main/kotlin/org/onflow/flow/sdk/models.kt (13 hunks)
🧰 Additional context used
🔇 Additional comments (10)
sdk/src/main/kotlin/org/onflow/flow/sdk/models.kt (10)

196-203: [Skip]: Previous comment still valid regarding lazy initialization.

The suggestion to lazily initialize the encoded property in FlowAccountKey was previously mentioned and remains applicable.


317-323: Efficient Filtering in getEventsOfType Method

The filtering logic for events based on the type is correctly implemented.


459-464: Optimized signerMap Implementation Looks Good

The use of associate with withIndex() efficiently maps signers to their indices.


788-800: FlowChunk Builder Method Implemented Correctly

The builder method accurately sets all required fields, ensuring proper serialization.


845-849: FlowServiceEvent Builder Method is Correct

Fields type and payload are appropriately set using ByteString.copyFrom.


881-887: [Skip]: Previous comment about duplicate of methods is still valid

The suggestion to refactor the duplicate of methods in FlowExecutionResult remains applicable.


920-966: FlowTimeoutCertificate Implementation is Accurate

All properties are correctly mapped and the methods are properly implemented, including equals and hashCode.


968-1007: FlowQuorumCertificate Class is Well-Defined

The class correctly encapsulates the necessary properties and provides accurate mappings.


1156-1200: FlowCollectionGuarantee Updates Look Good

New properties are added, and the serialization/deserialization methods correctly handle them.


1431-1460: [Skip]: Previous comment on validation in FlowCompatibleRange is still valid

The recommendation to add validation or default values to FlowCompatibleRange remains applicable.

@lealobanov lealobanov merged commit db9e3d1 into main Oct 17, 2024
3 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Update GetNodeVersionInfo response object
2 participants