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

Harmony rpc #1735

Merged
merged 19 commits into from
Apr 18, 2024
Merged

Harmony rpc #1735

merged 19 commits into from
Apr 18, 2024

Conversation

trajan0x
Copy link
Contributor

@trajan0x trajan0x commented Jan 4, 2024

Description
A clear and concise description of the features you're adding in this pull request.

Additional context
Add any other context about the problem you're solving.

Metadata

  • Fixes #[Link to Issue]

Summary by CodeRabbit

  • New Features

    • Added support for Harmony blockchain, including log filtering and transaction receipt retrieval.
    • Introduced a new proxy service for handling requests in omnirpc.
    • Enhanced Ethereum Virtual Machine interface to include web3 version retrieval.
  • Enhancements

    • Updated RPC methods to support new blockchain operations and client version retrieval.

@trajan0x trajan0x closed this Jan 4, 2024
Copy link
Contributor

coderabbitai bot commented Jan 4, 2024

Walkthrough

This update enriches the ethergo client with new features for Harmony blockchain interaction and extends the EVM interface to include a method for fetching the web3 version. Additionally, a new SimpleProxy type in the omnirpc service is introduced to efficiently handle proxy requests, supporting advanced filtering and request processing.

Changes

File Path Change Summary
ethergo/client/client.go Added Web3Version method, updated DialBackend, minor comments, and TODO updates.
ethergo/client/hmy.go Introduces Harmony blockchain interaction, methods for log filtering, and transaction receipt retrieval.
ethergo/client/methods.go Added RPC methods for Harmony operations and Web3VersionMethod. Updated RPC methods list.
services/omnirpc/proxy/simpleproxy.go Introduced SimpleProxy type for managing proxy requests, creation, execution, and specific request handling.

🐰✨🌟
O hark! New code doth gleam and shine,
With Harmony's touch, oh so divine.
Web3 whispers through the line,
In ethers vast, our codes combine.
Proxy dances, logs align. 🌐🎉
🐰✨🌟


Recent Review Details

Configuration used: .coderabbit.yaml

Commits Files that changed from the base of the PR and between 6a2ccf9 and a76559c.
Files selected for processing (9)
  • ethergo/backends/geth/geth.go (2 hunks)
  • ethergo/backends/mocks/simulated_test_backend.go (1 hunks)
  • ethergo/backends/simulated/chain.go (1 hunks)
  • ethergo/chain/client/client.go (3 hunks)
  • ethergo/chain/client/lifecycle.go (1 hunks)
  • ethergo/chain/client/mocks/evm_client.go (1 hunks)
  • ethergo/chain/client/mocks/metered_evm_client.go (1 hunks)
  • ethergo/chain/mocks/chain.go (1 hunks)
  • ethergo/submitter/config/iconfig_generated.go (1 hunks)
Files not reviewed due to errors (1)
  • simulated_test_backend.go (no review received)
Additional comments not posted (8)
ethergo/submitter/config/iconfig_generated.go (1)

18-19: Corrected method name from "maximum" to "minimum" enhances clarity and correctness.

ethergo/chain/client/client.go (2)

57-58: Added method Web3Version to the EVMClient interface to fetch the web3 version.


80-86: Implementation of Web3Version in clientImpl correctly uses an RPC call to fetch the version. Ensure error handling is robust around this network call.

ethergo/backends/geth/geth.go (1)

257-263: Method Web3Version added to wrappedClient correctly fetches the web3 version using an RPC call. Consistent with other implementations and well-handled.

ethergo/chain/client/lifecycle.go (1)

507-521: Method Web3Version added to LifecycleClient correctly manages permits around the fetching of the web3 version. This is crucial for resource management in concurrent environments.

ethergo/chain/client/mocks/evm_client.go (1)

779-798: The implementation of the Web3Version mock method looks correct and aligns with the typical structure of mock methods using the testify library.

ethergo/chain/client/mocks/metered_evm_client.go (1)

835-854: The implementation of the Web3Version mock method in MeteredEVMClient looks correct and follows the expected structure for mock methods using the testify library.

ethergo/chain/mocks/chain.go (1)

993-1012: The implementation of the Web3Version mock function looks correct and aligns with the expected functionality.


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

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

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

CodeRabbit Commands (invoked as PR comments)

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

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

CodeRabbit Configration File (.coderabbit.yaml)

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

Documentation and Community

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

@trajan0x trajan0x deleted the feat/omnirpc-double branch January 4, 2024 13:25
@github-actions github-actions bot added go Pull requests that update Go code size/m labels Jan 4, 2024
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.

Review Status

Actionable comments generated: 6

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 651ac00 and ecbedad.
Files selected for processing (10)
  • ethergo/client/capture_client.go (3 hunks)
  • ethergo/client/client.go (3 hunks)
  • ethergo/client/hmy.go (1 hunks)
  • ethergo/client/methods.go (1 hunks)
  • ethergo/client/mocks/evm.go (1 hunks)
  • services/omnirpc/cmd/cmd.go (1 hunks)
  • services/omnirpc/cmd/commands.go (1 hunks)
  • services/omnirpc/cmd/flags.go (1 hunks)
  • services/omnirpc/metadata/buildinfo.go (1 hunks)
  • services/omnirpc/proxy/simpleproxy.go (1 hunks)
Additional comments: 13
services/omnirpc/cmd/flags.go (1)
  • 44-47: The addition of rpcFlag is consistent with the existing pattern of flag declarations and is necessary for specifying the RPC URL.
services/omnirpc/cmd/cmd.go (1)
  • 25-25: The addition of the latestRewrite command to the app.Commands slice should be verified for correct integration with the existing command-line interface.
ethergo/client/capture_client.go (1)
  • 18-18: The addition of the rpcClient field to the captureClient struct is consistent with the existing structure pattern and is properly initialized in the newCaptureClient function.
ethergo/client/hmy.go (1)
  • 14-20: The HarmonyVM interface is a well-defined extension of the EVM interface, providing Harmony-specific methods. Ensure that these new methods are consistently used throughout the application.
Verification successful

The search results indicate that the HarmonyVM interface and its methods FilterHarmonyLogs and HarmonyTransactionReceipt are defined in ethergo/client/hmy.go and are used in services/omnirpc/proxy/simpleproxy.go. This suggests that the new Harmony-specific methods are indeed being utilized within the application.

  • The HarmonyVM interface is defined and includes the methods FilterHarmonyLogs and HarmonyTransactionReceipt.
  • The harmonyClient struct implements these methods.
  • The simpleproxy.go file uses the HarmonyTransactionReceipt method, indicating integration of the new functionality into the proxy service.

Based on the information provided, it appears that the new Harmony-specific methods are being used consistently within the application.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that the new Harmony-specific methods are used consistently.
rg --type go "HarmonyVM|FilterHarmonyLogs|HarmonyTransactionReceipt"

Length of output: 1315

ethergo/client/methods.go (2)
  • 63-66: The new Harmony RPC methods HarmonyGetLogsMethod and HarmonyGetReceiptMethod are correctly added and follow the existing pattern of RPC method declarations.

  • 72-72: The modification of NetVersionMethod appears redundant as the value remains unchanged. Please confirm if this change was intentional.

services/omnirpc/cmd/commands.go (1)
  • 158-174: The latestRewrite command is correctly added with appropriate flags for RPC and port configurations, and the action to run a simple proxy is well-defined.
services/omnirpc/proxy/simpleproxy.go (2)
  • 56-88: The Run method sets up the HTTP server and routes. It is important to ensure that the server is only accessible within a secure and controlled network environment, as binding to 0.0.0.0 allows connections from any IP address.

  • 158-207: The verifyHarmonyRequest method handles Harmony-specific requests. It is important to ensure that the Harmony node being proxied to is trusted, as the proxy forwards requests and potentially sensitive data.

ethergo/client/client.go (3)
  • 55-56: The addition of the Web3Version method to the EVM interface and its implementation in clientImpl is consistent with the PR's objective to extend blockchain support.

  • 85-85: The assignment of the rpcClient field in the DialBackend function is correctly done using the captureClient created within the same function.

  • 263-277: The implementation of the Web3Version method in the clientImpl struct is correct, with proper error handling and tracing.

ethergo/client/mocks/evm.go (1)
  • 779-798: The addition of the Web3Version mock function is correctly implemented and follows the standard mock function pattern used in this file.

@@ -10,5 +10,5 @@ var (

// BuildInfo returns the build info for the service.
func BuildInfo() config.BuildInfo {
return config.NewBuildInfo(version, commit, "omnirpc", date)
return config.NewBuildInfo(version, commit, "omnirpcharmony", date)
Copy link
Contributor

Choose a reason for hiding this comment

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

The search for the string "omnirpcharmony" within Go files only returned a single occurrence, which is in the services/omnirpc/metadata/buildinfo.go file. This suggests that the new service name "omnirpcharmony" is not used elsewhere in the application, at least not in the Go source files.

  • The BuildInfo function in services/omnirpc/metadata/buildinfo.go has been updated to use "omnirpcharmony" as the service name.
  • The string "omnirpcharmony" does not appear in any other Go files in the application.

Given this information, it is not possible to confirm that the new service name is consistent with the rest of the application, as it appears to be introduced here and not used elsewhere.

Analysis chain

The change in the service name within the BuildInfo function to "omnirpcharmony" should be consistent with the service's naming conventions and usage throughout the application.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that the new service name is used consistently across the application.
rg --type go "omnirpcharmony"

Length of output: 137

services/omnirpc/proxy/simpleproxy.go Outdated Show resolved Hide resolved
services/omnirpc/proxy/simpleproxy.go Outdated Show resolved Hide resolved
Comment on lines 238 to 353
g.Go(func() error {
harmonyReceipt, err = hmyClient.HarmonyTransactionReceipt(gCtx, txHash)
if err != nil {
return fmt.Errorf("could not get harmony receipt: %w", err)
}
return nil
})

var rpcMessage JSONRPCMessage

g.Go(func() error {
/// no need to double up on this check when doing receipts
if checkVersion {
web3Version, err := hmyClient.Web3Version(gCtx)
if err != nil {
return fmt.Errorf("could not get web3 version: %w", err)
}

if !strings.Contains(web3Version, expectedVersion) {
return fmt.Errorf("expected version %s, got %s", expectedVersion, web3Version)
}
}
return nil
})

g.Go(func() error {
rawResp, err = r.makeReq(ctx, rawBody)
if err != nil {
return fmt.Errorf("could not make req: %w", err)
}

err = json.Unmarshal(rawResp, &rpcMessage)
if err != nil {
return fmt.Errorf("could not unmarshal: %w", err)
}

err = json.Unmarshal(rpcMessage.Result, &ethReceipt)
if err != nil {
return fmt.Errorf("could not unmarshal eth receipt: %w", err)
}
return nil
})

err = g.Wait()
if err != nil {
return nil, fmt.Errorf("could not get receipts: %w", err)
}

if harmonyReceipt.BlockHash != ethReceipt.BlockHash {
return nil, fmt.Errorf("expected block hash %s, got %s", harmonyReceipt.BlockHash, ethReceipt.BlockHash)
}

if harmonyReceipt.TxHash == ethReceipt.TxHash {
return nil, fmt.Errorf("expected different tx hashes %s, got %s", harmonyReceipt.TxHash, ethReceipt.TxHash)
}

if harmonyReceipt.Status != ethReceipt.Status {
return nil, fmt.Errorf("expected tx index %d, got %d", harmonyReceipt.Status, ethReceipt.Status)
}

if harmonyReceipt.CumulativeGasUsed != ethReceipt.CumulativeGasUsed {
return nil, fmt.Errorf("expected index %d, got %d", harmonyReceipt.CumulativeGasUsed, ethReceipt.CumulativeGasUsed)
}

if harmonyReceipt.GasUsed != ethReceipt.GasUsed {
return nil, fmt.Errorf("expected index %d, got %d", harmonyReceipt.GasUsed, ethReceipt.GasUsed)
}

if len(harmonyReceipt.Logs) != len(ethReceipt.Logs) {
return nil, fmt.Errorf("expected %d logs, got %d", len(harmonyReceipt.Logs), len(ethReceipt.Logs))
}

for i := 0; i < len(harmonyReceipt.Logs); i++ {
ethReceipt.Logs[i].TxHash = ethReceipt.TxHash
}

receiptLogsMarshall, err := json.Marshal(ethReceipt.Logs)
if err != nil {
return nil, fmt.Errorf("could not marshal eth receipt: %w", err)
}

var fields map[string]json.RawMessage
err = json.Unmarshal(rpcMessage.Result, &fields)
if err != nil {
return nil, fmt.Errorf("could not unmarshal fields: %w", err)
}

fields["logs"] = json.RawMessage(receiptLogsMarshall)
rpcMessage.Result, err = json.Marshal(fields)
if err != nil {
return nil, fmt.Errorf("could not marshal fields: %w", err)
}

rawResp, err = json.Marshal(rpcMessage)
if err != nil {
return nil, fmt.Errorf("could not marshal rpc message: %w", err)
}

return rawResp, nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The getHarmonyReceiptVerify method performs parallel requests to verify Harmony transaction receipts. It is crucial to handle potential data races when accessing shared resources in goroutines, such as err in line 255. Use a local variable for error handling within each goroutine to avoid data races.

- harmonyReceipt, err = hmyClient.HarmonyTransactionReceipt(gCtx, txHash)
+ harmonyReceipt, goroutineErr := hmyClient.HarmonyTransactionReceipt(gCtx, txHash)
+ if goroutineErr != nil {
+   return fmt.Errorf("could not get harmony receipt: %w", goroutineErr)
+ }

Committable suggestion

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

Suggested change
func (r *SimpleProxy) getHarmonyReceiptVerify(parentCtx context.Context, txHash common.Hash, rawBody []byte, checkVersion bool) (_ []byte, err error) {
ctx, span := r.tracer.Start(parentCtx, "getHarmonyReceiptVerify")
defer func() {
metrics.EndSpanWithErr(span, err)
}()
hmyClient, err := client.DialHarmonyBackend(ctx, r.proxyURL, r.handler, client.Capture(true))
if err != nil {
return nil, fmt.Errorf("could not dial harmony backend: %w", err)
}
var harmonyReceipt, ethReceipt *types.Receipt
var rawResp []byte
g, gCtx := errgroup.WithContext(ctx)
g.Go(func() error {
harmonyReceipt, err = hmyClient.HarmonyTransactionReceipt(gCtx, txHash)
if err != nil {
return fmt.Errorf("could not get harmony receipt: %w", err)
}
return nil
})
var rpcMessage JSONRPCMessage
g.Go(func() error {
/// no need to double up on this check when doing receipts
if checkVersion {
web3Version, err := hmyClient.Web3Version(gCtx)
if err != nil {
return fmt.Errorf("could not get web3 version: %w", err)
}
if !strings.Contains(web3Version, expectedVersion) {
return fmt.Errorf("expected version %s, got %s", expectedVersion, web3Version)
}
}
return nil
})
g.Go(func() error {
rawResp, err = r.makeReq(ctx, rawBody)
if err != nil {
return fmt.Errorf("could not make req: %w", err)
}
err = json.Unmarshal(rawResp, &rpcMessage)
if err != nil {
return fmt.Errorf("could not unmarshal: %w", err)
}
err = json.Unmarshal(rpcMessage.Result, &ethReceipt)
if err != nil {
return fmt.Errorf("could not unmarshal eth receipt: %w", err)
}
return nil
})
err = g.Wait()
if err != nil {
return nil, fmt.Errorf("could not get receipts: %w", err)
}
if harmonyReceipt.BlockHash != ethReceipt.BlockHash {
return nil, fmt.Errorf("expected block hash %s, got %s", harmonyReceipt.BlockHash, ethReceipt.BlockHash)
}
if harmonyReceipt.TxHash == ethReceipt.TxHash {
return nil, fmt.Errorf("expected different tx hashes %s, got %s", harmonyReceipt.TxHash, ethReceipt.TxHash)
}
if harmonyReceipt.Status != ethReceipt.Status {
return nil, fmt.Errorf("expected tx index %d, got %d", harmonyReceipt.Status, ethReceipt.Status)
}
if harmonyReceipt.CumulativeGasUsed != ethReceipt.CumulativeGasUsed {
return nil, fmt.Errorf("expected index %d, got %d", harmonyReceipt.CumulativeGasUsed, ethReceipt.CumulativeGasUsed)
}
if harmonyReceipt.GasUsed != ethReceipt.GasUsed {
return nil, fmt.Errorf("expected index %d, got %d", harmonyReceipt.GasUsed, ethReceipt.GasUsed)
}
if len(harmonyReceipt.Logs) != len(ethReceipt.Logs) {
return nil, fmt.Errorf("expected %d logs, got %d", len(harmonyReceipt.Logs), len(ethReceipt.Logs))
}
for i := 0; i < len(harmonyReceipt.Logs); i++ {
ethReceipt.Logs[i].TxHash = ethReceipt.TxHash
}
receiptLogsMarshall, err := json.Marshal(ethReceipt.Logs)
if err != nil {
return nil, fmt.Errorf("could not marshal eth receipt: %w", err)
}
var fields map[string]json.RawMessage
err = json.Unmarshal(rpcMessage.Result, &fields)
if err != nil {
return nil, fmt.Errorf("could not unmarshal fields: %w", err)
}
fields["logs"] = json.RawMessage(receiptLogsMarshall)
rpcMessage.Result, err = json.Marshal(fields)
if err != nil {
return nil, fmt.Errorf("could not marshal fields: %w", err)
}
rawResp, err = json.Marshal(rpcMessage)
if err != nil {
return nil, fmt.Errorf("could not marshal rpc message: %w", err)
}
return rawResp, nil
}
g.Go(func() error {
harmonyReceipt, goroutineErr := hmyClient.HarmonyTransactionReceipt(gCtx, txHash)
if goroutineErr != nil {
return fmt.Errorf("could not get harmony receipt: %w", goroutineErr)
}
return nil
})

Comment on lines 355 to 463
return nil, fmt.Errorf("could not dial harmony backend: %w", err)
}

var ethLogs []types.Log
var rpcMessage JSONRPCMessage

g, gCtx := errgroup.WithContext(ctx)
g.Go(func() error {
web3Version, err := hmyClient.Web3Version(gCtx)
if err != nil {
return fmt.Errorf("could not get web3 version: %w", err)
}

if !strings.Contains(web3Version, expectedVersion) {
return fmt.Errorf("expected version %s, got %s", expectedVersion, web3Version)
}
return nil
})

g.Go(func() error {
rawResp, err = r.makeReq(ctx, rawBody)
if err != nil {
return fmt.Errorf("could not make req: %w", err)
}

err = json.Unmarshal(rawResp, &rpcMessage)
if err != nil {
return fmt.Errorf("could not unmarshal: %w", err)
}

err = json.Unmarshal(rpcMessage.Result, &ethLogs)
if err != nil {
return fmt.Errorf("could not unmarshal eth receipt: %w", err)
}

return nil
})

err = g.Wait()
if err != nil {
return nil, fmt.Errorf("could not get logs: %w", err)
}

uniqueHashes := sets.NewString()
for i := 0; i < len(ethLogs); i++ {
uniqueHashes.Insert(ethLogs[i].TxHash.String())
}

g, gCtx = errgroup.WithContext(ctx)
var logs []*types.Log
var mux sync.Mutex
for _, hash := range uniqueHashes.List() {
g.Go(func() error {
rawReqBody, err := json.Marshal(rpc.Request{
ID: 1,
Method: client.TransactionReceiptByHashMethod.String(),
Params: []json.RawMessage{json.RawMessage(fmt.Sprintf("\"%s\"", hash))},
})

resp, err := r.getHarmonyReceiptVerify(gCtx, common.HexToHash(hash), rawReqBody, false)
if err != nil {
return fmt.Errorf("could not get harmony receipt: %w", err)
}

var rpcMessage JSONRPCMessage
err = json.Unmarshal(resp, &rpcMessage)
if err != nil {
return fmt.Errorf("could not unmarshal: %w", err)
}

var receipt types.Receipt
err = json.Unmarshal(rpcMessage.Result, &receipt)
if err != nil {
return fmt.Errorf("could not unmarshal: %w", err)
}

mux.Lock()
logs = append(logs, receipt.Logs...)
mux.Unlock()
return nil
})
}

err = g.Wait()
if err != nil {
return nil, fmt.Errorf("could not get logs: %w", err)
}

filteredLogs := filterLogs(logs, query.FromBlock, query.ToBlock, query.Addresses, query.Topics)
if err != nil {
return nil, fmt.Errorf("could not filter logs: %w", err)
}

rpcMessage.Result, err = json.Marshal(filteredLogs)
if err != nil {
return nil, fmt.Errorf("could not marshal fields: %w", err)
}

return rawResp, nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The getLogsHarmonyVerify method contains a potential error handling issue. The error check on line 453 is redundant and will never be true because err is not reassigned after its declaration. This check should be removed or corrected to check the actual error returned from the filterLogs function.

- if err != nil {
+ // Assuming filterLogs returns an error, which is not shown in the current context.
+ filteredLogs, filterErr := filterLogs(logs, query.FromBlock, query.ToBlock, query.Addresses, query.Topics)
+ if filterErr != nil {
    return nil, fmt.Errorf("could not filter logs: %w", err)
  }

Committable suggestion

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

Suggested change
func (r *SimpleProxy) getLogsHarmonyVerify(parentCtx context.Context, query ethereum.FilterQuery, rawBody []byte) (rawResp []byte, err error) {
ctx, span := r.tracer.Start(parentCtx, "getLogsHarmonyVerify")
defer func() {
metrics.EndSpanWithErr(span, err)
}()
hmyClient, err := client.DialHarmonyBackend(ctx, r.proxyURL, r.handler, client.Capture(true))
if err != nil {
return nil, fmt.Errorf("could not dial harmony backend: %w", err)
}
var ethLogs []types.Log
var rpcMessage JSONRPCMessage
g, gCtx := errgroup.WithContext(ctx)
g.Go(func() error {
web3Version, err := hmyClient.Web3Version(gCtx)
if err != nil {
return fmt.Errorf("could not get web3 version: %w", err)
}
if !strings.Contains(web3Version, expectedVersion) {
return fmt.Errorf("expected version %s, got %s", expectedVersion, web3Version)
}
return nil
})
g.Go(func() error {
rawResp, err = r.makeReq(ctx, rawBody)
if err != nil {
return fmt.Errorf("could not make req: %w", err)
}
err = json.Unmarshal(rawResp, &rpcMessage)
if err != nil {
return fmt.Errorf("could not unmarshal: %w", err)
}
err = json.Unmarshal(rpcMessage.Result, &ethLogs)
if err != nil {
return fmt.Errorf("could not unmarshal eth receipt: %w", err)
}
return nil
})
err = g.Wait()
if err != nil {
return nil, fmt.Errorf("could not get logs: %w", err)
}
uniqueHashes := sets.NewString()
for i := 0; i < len(ethLogs); i++ {
uniqueHashes.Insert(ethLogs[i].TxHash.String())
}
g, gCtx = errgroup.WithContext(ctx)
var logs []*types.Log
var mux sync.Mutex
for _, hash := range uniqueHashes.List() {
g.Go(func() error {
rawReqBody, err := json.Marshal(rpc.Request{
ID: 1,
Method: client.TransactionReceiptByHashMethod.String(),
Params: []json.RawMessage{json.RawMessage(fmt.Sprintf("\"%s\"", hash))},
})
resp, err := r.getHarmonyReceiptVerify(gCtx, common.HexToHash(hash), rawReqBody, false)
if err != nil {
return fmt.Errorf("could not get harmony receipt: %w", err)
}
var rpcMessage JSONRPCMessage
err = json.Unmarshal(resp, &rpcMessage)
if err != nil {
return fmt.Errorf("could not unmarshal: %w", err)
}
var receipt types.Receipt
err = json.Unmarshal(rpcMessage.Result, &receipt)
if err != nil {
return fmt.Errorf("could not unmarshal: %w", err)
}
mux.Lock()
logs = append(logs, receipt.Logs...)
mux.Unlock()
return nil
})
}
err = g.Wait()
if err != nil {
return nil, fmt.Errorf("could not get logs: %w", err)
}
filteredLogs := filterLogs(logs, query.FromBlock, query.ToBlock, query.Addresses, query.Topics)
if err != nil {
return nil, fmt.Errorf("could not filter logs: %w", err)
}
rpcMessage.Result, err = json.Marshal(filteredLogs)
if err != nil {
return nil, fmt.Errorf("could not marshal fields: %w", err)
}
return rawResp, nil
}
filteredLogs, filterErr := filterLogs(logs, query.FromBlock, query.ToBlock, query.Addresses, query.Topics)
if filterErr != nil {
return nil, fmt.Errorf("could not filter logs: %w", filterErr)
}

Comment on lines 465 to 509
// filterLogs creates a slice of logs matching the given criteria.
func filterLogs(logs []*types.Log, fromBlock, toBlock *big.Int, addresses []common.Address, topics [][]common.Hash) []*types.Log {
var ret []*types.Log
Logs:
for _, log := range logs {
if fromBlock != nil && fromBlock.Int64() >= 0 && fromBlock.Uint64() > log.BlockNumber {
continue
}
if toBlock != nil && toBlock.Int64() >= 0 && toBlock.Uint64() < log.BlockNumber {
continue
}

if len(addresses) > 0 && !includes(addresses, log.Address) {
continue
}
// If the to filtered topics is greater than the amount of topics in logs, skip.
if len(topics) > len(log.Topics) {
continue
}
for i, sub := range topics {
match := len(sub) == 0 // empty rule set == wildcard
for _, topic := range sub {
if log.Topics[i] == topic {
match = true
break
}
}
if !match {
continue Logs
}
}
ret = append(ret, log)
}
return ret
}

func includes(addresses []common.Address, a common.Address) bool {
for _, addr := range addresses {
if addr == a {
return true
}
}

return false
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The filterLogs and includes functions are utility functions used to filter logs based on certain criteria. Ensure that these functions are covered by unit tests to validate their correctness and performance, especially since they are likely to be called with a large number of logs.

@trajan0x trajan0x restored the feat/omnirpc-double branch January 26, 2024 18:09
@trajan0x trajan0x reopened this Jan 26, 2024
Copy link

codecov bot commented Jan 26, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 47.04104%. Comparing base (f5a7f22) to head (a76559c).
Report is 2 commits behind head on master.

Additional details and impacted files
@@                 Coverage Diff                 @@
##              master       #1735         +/-   ##
===================================================
- Coverage   47.05001%   47.04104%   -0.00897%     
===================================================
  Files            384         401         +17     
  Lines          29373       30754       +1381     
  Branches          83          83                 
===================================================
+ Hits           13820       14467        +647     
- Misses         14102       14765        +663     
- Partials        1451        1522         +71     
Flag Coverage Δ
cctp-relayer 43.53414% <ø> (?)
committee 63.75176% <ø> (ø)
omnirpc 53.23194% <ø> (ø)
promexporter 75.91241% <ø> (?)
stiprelayer 3.33333% <ø> (ø)
tools 21.98661% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

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.

Review Status

Actionable comments generated: 3

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between ecbedad and 37247198ef90e9b87d82251add2675acda2a922b.
Files selected for processing (1)
  • services/omnirpc/proxy/simpleproxy.go (1 hunks)
Additional comments: 2
services/omnirpc/proxy/simpleproxy.go (2)
  • 91-91: The ProxyRequest method does not support batch requests, which is indicated by the error on line 91. Ensure that this limitation is documented in the user-facing API documentation.
  • 465-509: The filterLogs and includes functions are utility functions used to filter logs based on certain criteria. Ensure that these functions are covered by unit tests to validate their correctness and performance, especially since they are likely to be called with a large number of logs.

proxyURL string
}

// NewSimpleProxy creates a new simply proxy
Copy link
Contributor

Choose a reason for hiding this comment

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

The comment on line 43 has a typo: "simply" should be "simple".

- // NewSimpleProxy creates a new simply proxy
+ // NewSimpleProxy creates a new simple proxy

Committable suggestion

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

Suggested change
// NewSimpleProxy creates a new simply proxy
// NewSimpleProxy creates a new simple proxy

Comment on lines 238 to 255
func (r *SimpleProxy) getHarmonyReceiptVerify(parentCtx context.Context, txHash common.Hash, rawBody []byte, checkVersion bool) (_ []byte, err error) {
ctx, span := r.tracer.Start(parentCtx, "getHarmonyReceiptVerify")

defer func() {
metrics.EndSpanWithErr(span, err)
}()

hmyClient, err := client.DialHarmonyBackend(ctx, r.proxyURL, r.handler, client.Capture(true))
if err != nil {
return nil, fmt.Errorf("could not dial harmony backend: %w", err)
}

var harmonyReceipt, ethReceipt *types.Receipt
var rawResp []byte
g, gCtx := errgroup.WithContext(ctx)

g.Go(func() error {
harmonyReceipt, err = hmyClient.HarmonyTransactionReceipt(gCtx, txHash)
Copy link
Contributor

@coderabbitai coderabbitai bot Jan 26, 2024

Choose a reason for hiding this comment

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

The getHarmonyReceiptVerify method performs parallel requests to verify Harmony transaction receipts. It is crucial to handle potential data races when accessing shared resources in goroutines, such as err in line 255. Use a local variable for error handling within each goroutine to avoid data races.

- harmonyReceipt, err = hmyClient.HarmonyTransactionReceipt(gCtx, txHash)
+ harmonyReceipt, goroutineErr := hmyClient.HarmonyTransactionReceipt(gCtx, txHash)
+ if goroutineErr != nil {
+   return fmt.Errorf("could not get harmony receipt: %w", goroutineErr)
+ }

Committable suggestion

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

Suggested change
func (r *SimpleProxy) getHarmonyReceiptVerify(parentCtx context.Context, txHash common.Hash, rawBody []byte, checkVersion bool) (_ []byte, err error) {
ctx, span := r.tracer.Start(parentCtx, "getHarmonyReceiptVerify")
defer func() {
metrics.EndSpanWithErr(span, err)
}()
hmyClient, err := client.DialHarmonyBackend(ctx, r.proxyURL, r.handler, client.Capture(true))
if err != nil {
return nil, fmt.Errorf("could not dial harmony backend: %w", err)
}
var harmonyReceipt, ethReceipt *types.Receipt
var rawResp []byte
g, gCtx := errgroup.WithContext(ctx)
g.Go(func() error {
harmonyReceipt, err = hmyClient.HarmonyTransactionReceipt(gCtx, txHash)
harmonyReceipt, goroutineErr := hmyClient.HarmonyTransactionReceipt(gCtx, txHash)
if goroutineErr != nil {
return fmt.Errorf("could not get harmony receipt: %w", goroutineErr)
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

these will get shadoed anway so this won't interfere wiht parent, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

@trajan0x, you are correct that the goroutineErr variable declared within the goroutine will be local to that goroutine and will not interfere with the err variable in the parent scope. In Go, each goroutine operates with its own stack, and variables declared within a goroutine are scoped to that goroutine. This means that goroutineErr is completely independent of the err variable used outside the goroutine, effectively preventing any potential data races or interference between them.

This approach ensures that error handling within each goroutine is isolated, enhancing the robustness of the error management strategy in concurrent environments. If you have any more questions or need further clarification, feel free to ask!

Comment on lines 355 to 453
func (r *SimpleProxy) getLogsHarmonyVerify(parentCtx context.Context, query ethereum.FilterQuery, rawBody []byte) (rawResp []byte, err error) {
ctx, span := r.tracer.Start(parentCtx, "getLogsHarmonyVerify")

defer func() {
metrics.EndSpanWithErr(span, err)
}()

hmyClient, err := client.DialHarmonyBackend(ctx, r.proxyURL, r.handler, client.Capture(true))
if err != nil {
return nil, fmt.Errorf("could not dial harmony backend: %w", err)
}

var ethLogs []types.Log
var rpcMessage JSONRPCMessage

g, gCtx := errgroup.WithContext(ctx)
g.Go(func() error {
web3Version, err := hmyClient.Web3Version(gCtx)
if err != nil {
return fmt.Errorf("could not get web3 version: %w", err)
}

if !strings.Contains(web3Version, expectedVersion) {
return fmt.Errorf("expected version %s, got %s", expectedVersion, web3Version)
}
return nil
})

g.Go(func() error {
rawResp, err = r.makeReq(ctx, rawBody)
if err != nil {
return fmt.Errorf("could not make req: %w", err)
}

err = json.Unmarshal(rawResp, &rpcMessage)
if err != nil {
return fmt.Errorf("could not unmarshal: %w", err)
}

err = json.Unmarshal(rpcMessage.Result, &ethLogs)
if err != nil {
return fmt.Errorf("could not unmarshal eth receipt: %w", err)
}

return nil
})

err = g.Wait()
if err != nil {
return nil, fmt.Errorf("could not get logs: %w", err)
}

uniqueHashes := sets.NewString()
for i := 0; i < len(ethLogs); i++ {
uniqueHashes.Insert(ethLogs[i].TxHash.String())
}

g, gCtx = errgroup.WithContext(ctx)
var logs []*types.Log
var mux sync.Mutex
for _, hash := range uniqueHashes.List() {
g.Go(func() error {
rawReqBody, err := json.Marshal(rpc.Request{
ID: 1,
Method: client.TransactionReceiptByHashMethod.String(),
Params: []json.RawMessage{json.RawMessage(fmt.Sprintf("\"%s\"", hash))},
})

resp, err := r.getHarmonyReceiptVerify(gCtx, common.HexToHash(hash), rawReqBody, false)
if err != nil {
return fmt.Errorf("could not get harmony receipt: %w", err)
}

var rpcMessage JSONRPCMessage
err = json.Unmarshal(resp, &rpcMessage)
if err != nil {
return fmt.Errorf("could not unmarshal: %w", err)
}

var receipt types.Receipt
err = json.Unmarshal(rpcMessage.Result, &receipt)
if err != nil {
return fmt.Errorf("could not unmarshal: %w", err)
}

mux.Lock()
logs = append(logs, receipt.Logs...)
mux.Unlock()
return nil
})
}

err = g.Wait()
if err != nil {
return nil, fmt.Errorf("could not get logs: %w", err)
}

filteredLogs := filterLogs(logs, query.FromBlock, query.ToBlock, query.Addresses, query.Topics)
if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

The getLogsHarmonyVerify method contains a potential error handling issue. The error check on line 453 is redundant and will never be true because err is not reassigned after its declaration. This check should be removed or corrected to check the actual error returned from the filterLogs function.

- if err != nil {
+ // Assuming filterLogs returns an error, which is not shown in the current context.
+ filteredLogs, filterErr := filterLogs(logs, query.FromBlock, query.ToBlock, query.Addresses, query.Topics)
+ if filterErr != nil {
    return nil, fmt.Errorf("could not filter logs: %w", err)
  }

Committable suggestion

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

Suggested change
func (r *SimpleProxy) getLogsHarmonyVerify(parentCtx context.Context, query ethereum.FilterQuery, rawBody []byte) (rawResp []byte, err error) {
ctx, span := r.tracer.Start(parentCtx, "getLogsHarmonyVerify")
defer func() {
metrics.EndSpanWithErr(span, err)
}()
hmyClient, err := client.DialHarmonyBackend(ctx, r.proxyURL, r.handler, client.Capture(true))
if err != nil {
return nil, fmt.Errorf("could not dial harmony backend: %w", err)
}
var ethLogs []types.Log
var rpcMessage JSONRPCMessage
g, gCtx := errgroup.WithContext(ctx)
g.Go(func() error {
web3Version, err := hmyClient.Web3Version(gCtx)
if err != nil {
return fmt.Errorf("could not get web3 version: %w", err)
}
if !strings.Contains(web3Version, expectedVersion) {
return fmt.Errorf("expected version %s, got %s", expectedVersion, web3Version)
}
return nil
})
g.Go(func() error {
rawResp, err = r.makeReq(ctx, rawBody)
if err != nil {
return fmt.Errorf("could not make req: %w", err)
}
err = json.Unmarshal(rawResp, &rpcMessage)
if err != nil {
return fmt.Errorf("could not unmarshal: %w", err)
}
err = json.Unmarshal(rpcMessage.Result, &ethLogs)
if err != nil {
return fmt.Errorf("could not unmarshal eth receipt: %w", err)
}
return nil
})
err = g.Wait()
if err != nil {
return nil, fmt.Errorf("could not get logs: %w", err)
}
uniqueHashes := sets.NewString()
for i := 0; i < len(ethLogs); i++ {
uniqueHashes.Insert(ethLogs[i].TxHash.String())
}
g, gCtx = errgroup.WithContext(ctx)
var logs []*types.Log
var mux sync.Mutex
for _, hash := range uniqueHashes.List() {
g.Go(func() error {
rawReqBody, err := json.Marshal(rpc.Request{
ID: 1,
Method: client.TransactionReceiptByHashMethod.String(),
Params: []json.RawMessage{json.RawMessage(fmt.Sprintf("\"%s\"", hash))},
})
resp, err := r.getHarmonyReceiptVerify(gCtx, common.HexToHash(hash), rawReqBody, false)
if err != nil {
return fmt.Errorf("could not get harmony receipt: %w", err)
}
var rpcMessage JSONRPCMessage
err = json.Unmarshal(resp, &rpcMessage)
if err != nil {
return fmt.Errorf("could not unmarshal: %w", err)
}
var receipt types.Receipt
err = json.Unmarshal(rpcMessage.Result, &receipt)
if err != nil {
return fmt.Errorf("could not unmarshal: %w", err)
}
mux.Lock()
logs = append(logs, receipt.Logs...)
mux.Unlock()
return nil
})
}
err = g.Wait()
if err != nil {
return nil, fmt.Errorf("could not get logs: %w", err)
}
filteredLogs := filterLogs(logs, query.FromBlock, query.ToBlock, query.Addresses, query.Topics)
if err != nil {
filteredLogs, filterErr := filterLogs(logs, query.FromBlock, query.ToBlock, query.Addresses, query.Topics)
if filterErr != nil {

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.

Review Status

Actionable comments generated: 1

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 37247198ef90e9b87d82251add2675acda2a922b and a319d29b384acf707a1738bd8310e84e08664ebd.
Files selected for processing (1)
  • ethergo/client/client.go (3 hunks)
Additional comments: 2
ethergo/client/client.go (2)
  • 53-54: The addition of the Web3Version method to the EVM interface is a necessary update for supporting Harmony blockchain interactions. This method will allow the client to retrieve the web3 version, which is a fundamental aspect of interacting with Ethereum and Harmony blockchains.
  • 76-83: The update to the DialBackend method in the clientImpl struct, specifically the assignment to client.rpcClient, is crucial for ensuring that the RPC client is properly initialized. This change is necessary for the Web3Version method and potentially other RPC interactions to function correctly.

Comment on lines +232 to +277
// Web3Version calls Web3Version on the underlying client
//
//nolint:wrapcheck
func (c *clientImpl) Web3Version(ctx context.Context) (version string, err error) {
requestCtx, span := c.startSpan(ctx, Web3VersionMethod)
defer func() {
metrics.EndSpanWithErr(span, err)
}()

var ver string
if err := c.rpcClient.CallContext(requestCtx, &ver, Web3VersionMethod.String()); err != nil {
return "", err
}
return ver, nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The implementation of the Web3Version method in the clientImpl struct correctly calls the underlying RPC client to retrieve the web3 version. The use of CallContext for making the RPC call is appropriate, and the error handling is consistent with the rest of the file. However, consider adding a brief comment above the Web3Version method to explain its purpose, especially for developers unfamiliar with web3 or the specific needs of Harmony blockchain interactions.


Committable suggestion

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

Suggested change
// Web3Version calls Web3Version on the underlying client
//
//nolint:wrapcheck
func (c *clientImpl) Web3Version(ctx context.Context) (version string, err error) {
requestCtx, span := c.startSpan(ctx, Web3VersionMethod)
defer func() {
metrics.EndSpanWithErr(span, err)
}()
var ver string
if err := c.rpcClient.CallContext(requestCtx, &ver, Web3VersionMethod.String()); err != nil {
return "", err
}
return ver, nil
}
// Web3Version calls Web3Version on the underlying client
//
//nolint:wrapcheck
func (c *clientImpl) Web3Version(ctx context.Context) (version string, err error) {
requestCtx, span := c.startSpan(ctx, Web3VersionMethod)
defer func() {
metrics.EndSpanWithErr(span, err)
}()
var ver string
if err := c.rpcClient.CallContext(requestCtx, &ver, Web3VersionMethod.String()); err != nil {
return "", err
}
return ver, nil
}

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.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between a319d29b384acf707a1738bd8310e84e08664ebd and 7964800ef04f96c71e302d0a92b2efedb2bde820.
Files ignored due to path filters (1)
  • services/stiprelayer/go.mod is excluded by: !**/*.mod
Files selected for processing (1)
  • services/omnirpc/proxy/simpleproxy.go (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • services/omnirpc/proxy/simpleproxy.go

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.

Review Status

Actionable comments generated: 0

Configuration used: .coderabbit.yaml

Commits Files that changed from the base of the PR and between ecbedad and 77be159.
Files selected for processing (3)
  • ethergo/client/client.go (3 hunks)
  • ethergo/client/hmy.go (1 hunks)
  • ethergo/client/methods.go (1 hunks)
Additional comments: 14
ethergo/client/hmy.go (7)
  • 14-21: The HarmonyVM interface correctly extends the EVM interface with Harmony-specific methods. This design follows the principle of interface segregation, ensuring that Harmony-specific functionalities are encapsulated within this interface.
  • 23-25: The harmonyClient struct is correctly defined to embed the clientImpl struct, allowing it to inherit methods from the Ethereum client implementation while also implementing the HarmonyVM interface.
  • 27-38: The DialHarmonyBackend function is implemented correctly, ensuring that it returns an error if the underlying DialBackend call fails or if the type assertion fails. This ensures robust error handling and clear error messages for the caller.
  • 41-53: The FilterHarmonyLogs method correctly uses the startSpan method for tracing and metrics.EndSpanWithErr for error handling in the deferred function. The use of CallContext for making the RPC call is appropriate. However, ensure that the HarmonyGetLogsMethod is correctly implemented and registered in the RPC client.
  • 56-72: The HarmonyTransactionReceipt method follows the same pattern as FilterHarmonyLogs for tracing and error handling. The check for a nil receipt before returning ethereum.NotFound is a good practice to avoid returning misleading errors when the receipt is simply not found.
  • 75-93: The toFilterArg function correctly handles the conversion of an ethereum.FilterQuery to the format expected by the Harmony RPC methods. The error handling for mutually exclusive parameters (BlockHash and FromBlock/ToBlock) is correctly implemented.
  • 96-104: The toBlockNumArg function correctly handles the conversion of a block number to the string format expected by the RPC methods, including special cases for nil (latest) and -1 (pending).
ethergo/client/methods.go (3)
  • 64-71: The Harmony-specific RPC methods (HarmonyGetLogsMethod and HarmonyGetReceiptMethod) are correctly defined as constants of type RPCMethod. This ensures consistency with the existing Ethereum RPC methods.
  • 76-77: The addition of Web3VersionMethod to the NetMethods section is correctly implemented, following the pattern of other method definitions.
  • 83-83: The allMethods slice is correctly updated to include the new Harmony RPC methods and the Web3VersionMethod. This ensures that these methods are recognized and can be used throughout the client library.
ethergo/client/client.go (4)
  • 53-54: The addition of the Web3Version method to the EVM interface is correctly implemented, ensuring that implementations of the EVM interface provide a method to retrieve the web3 version.
  • 62-62: The rpcClient field is correctly added to the clientImpl struct, allowing the struct to hold a reference to the RPC client used for making calls to the Ethereum node.
  • 77-84: The DialBackend function is correctly updated to assign the rpcClient field of the clientImpl struct. This ensures that the rpcClient is available for use in methods that require making RPC calls.
  • 233-247: The implementation of the Web3Version method in the clientImpl struct correctly calls the underlying RPC client to retrieve the web3 version. The use of CallContext for making the RPC call is appropriate, and the error handling is consistent with the rest of the file.

Copy link

This PR is stale because it has been open 14 days with no activity. Remove stale label or comment or this will be closed in 5 days.

@github-actions github-actions bot added the Stale label Mar 11, 2024
@github-actions github-actions bot closed this Mar 17, 2024
Copy link

cloudflare-workers-and-pages bot commented Mar 21, 2024

Deploying sanguine-fe with  Cloudflare Pages  Cloudflare Pages

Latest commit: a76559c
Status: ✅  Deploy successful!
Preview URL: https://70bcfdea.sanguine-fe.pages.dev
Branch Preview URL: https://feat-omnirpc-double.sanguine-fe.pages.dev

View logs

Copy link

github-actions bot commented Apr 5, 2024

This PR is stale because it has been open 14 days with no activity. Remove stale label or comment or this will be closed in 5 days.

@github-actions github-actions bot added the Stale label Apr 5, 2024
@github-actions github-actions bot closed this Apr 10, 2024
@trajan0x trajan0x reopened this Apr 18, 2024
@trajan0x trajan0x removed the Stale label Apr 18, 2024
@trajan0x trajan0x removed the request for review from nautsimon April 18, 2024 12:05
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

Comment on lines +22 to +26
// Web3Version is not implemented on this backend.
func (s Client) Web3Version(_ context.Context) (version string, err error) {
// TODO implement me
panic("cannot implement on this backend")
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Method Web3Version is added but not implemented and will panic if called. Ensure this method is not used in production and consider documenting its non-implementation clearly.

// FeeHistory is not implemented on this backend.
func (s Client) FeeHistory(ctx context.Context, blockCount uint64, lastBlock *big.Int, rewardPercentiles []float64) (*ethereum.FeeHistory, error) {
func (s Client) FeeHistory(_ context.Context, _ uint64, _ *big.Int, _ []float64) (*ethereum.FeeHistory, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Method FeeHistory is similarly not implemented and will panic if called. As with Web3Version, ensure it is not used where it can cause runtime errors and document its limitations.

@trajan0x trajan0x merged commit c18c7c8 into master Apr 18, 2024
56 of 59 checks passed
@trajan0x trajan0x deleted the feat/omnirpc-double branch April 18, 2024 12:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant