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

Update Simulated Backend Client #10403

Merged
merged 7 commits into from
Sep 6, 2023
Merged

Conversation

EasterTheBunny
Copy link
Contributor

This commit aims to improve the simulated backend client by removing the block limit where only the latest block can be provided to CallContext and handling input args more gracefully.

  • CallContext will now only validate the block number passed in args
  • CallContext will NOT restrict calls to current block, but will pass nil to backend
  • from in call args is no longer required and will default to 0x
  • from and to accept common.Address, *big.Int and string types

Included is a move to Go standard error handling consistent with v1.20+ and error wrapping.

This commit aims to improve the simulated backend client by removing the block
limit where only the latest block can be provided to `CallContext` and handling
input args more gracefully.

- `CallContext` will now only validate the block number passed in args
- `CallContext` will NOT restrict calls to current block, but will pass nil to backend
- `from` in call args is no longer required and will default to `0x`
- `from` and `to` accept `common.Address`, `*big.Int` and `string` types

Included is a move to Go standard error handling consistent with v1.20+ and
error wrapping.
@github-actions
Copy link
Contributor

I see that you haven't updated any README files. Would it make sense to do so?

Comment on lines 96 to 97
default:
return common.HexToAddress("0x")
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe we should error instead of defaulting to 0x000.. if the arg is an unsupported type?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That would be less silent. I like it.

@@ -155,26 +184,26 @@ func init() {
var err error
balanceOfABI, err = abi.JSON(strings.NewReader(balanceOfABIString))
if err != nil {
panic(errors.Wrapf(err, "while parsing erc20ABI"))
panic(fmt.Errorf("%w: while parsing erc20ABI", err))
Copy link
Contributor

Choose a reason for hiding this comment

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

why get rid of errors.Wrap() ? We use it all over core and it kind of removes the debate over "how to wrap your errors"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We use it all over core because it predates the latest error wrapping features of Go. This is just making a small change in a single file to bring the code up to date with latest Go standards.

Copy link
Contributor

Choose a reason for hiding this comment

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

ahh I didn't realize that. Thanks for the explanation :)

Copy link
Contributor Author

@EasterTheBunny EasterTheBunny Aug 31, 2023

Choose a reason for hiding this comment

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

I did research this one a bit just to be sure so I'll add a bit more info here for anyone else interested in why this change.

  • github.com/pkg/errors is in maintenance mode because of the latest Go standard of wrapping errors
  • using errors.Is from the above package simply wraps the Go standard errors.Is so no threat from not using Wrap
  • go-ethereum returns errors in the standard format, so continuing that pattern in our own simulated client makes the most sense

} else {
ca.From = common.HexToAddress("0x")
}

return &ca, blockNumber, nil
Copy link
Contributor

Choose a reason for hiding this comment

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

what happens now if we pass an old block number? Does the backend error or does it just use latest anyway?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It will just use latest by default. This change makes the behavior of CallContext and BatchCallContext match regarding the block number passed to the simulated backend.

Comment on lines 1 to 9
/*
The simulated backend cannot access old blocks and will return an error if
anything other than `latest`, `nil`, or the latest block are passed to
`CallContract`.

The simulated client avoids the old block error from the simulated backend by
passing `nil` to `CallContract` when calling `CallContext` or `BatchCallContext`
and will not return an error when an old block is used.
*/
Copy link
Contributor

Choose a reason for hiding this comment

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

Does godoc pick this up as a package level comment? Is there a particular type we could associate it with instead?

Copy link
Contributor Author

@EasterTheBunny EasterTheBunny Sep 1, 2023

Choose a reason for hiding this comment

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

I added it to the top so that the behavior of two functions is well explained and visible. I could add the explanation to each of the functions in question CallContext and BatchCallContext as well to ensure the explanation is visible to IDE tools as well.

Copy link
Contributor Author

@EasterTheBunny EasterTheBunny Sep 1, 2023

Choose a reason for hiding this comment

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

There isn't a doc.go file in that package, but I can create one and move this comment there too.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmmm I thought a doc.go was just a convention for humans to find it in source. I don't think godoc and pkg.go.dev care about the file boundaries though 🤔
I usually run godoc -http=:6060 locally to try it out

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah it just puts all the detached floating file comments like this at the top in the overview:
image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Haha! Therefore it's duplicated. The preference would be to put it in doc.go then?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, unless there is a specific identifier to associate it with instead.

func interfaceToAddress(value interface{}) (common.Address, error) {
switch v := value.(type) {
case common.Address:
return v
Copy link
Contributor

Choose a reason for hiding this comment

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

missing return argument.
return v, nil

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ooops


ca.From = addr
} else {
ca.From = common.HexToAddress("0x")
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems weird. Why don't we just err here?
FromAddress being 0x will anyways not work i later part of code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have it like this because other parts of the code don't provide a 'From' value as I suppose the production client doesn't require it. I tried to model the simulated client to follow the same behavior.

}

// to and from need to map to a common.Address but could come in as a string
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: comment unaligned.
Maybe move the toAddr and fromAddr parsing before setting CallArgs, and put this comment there.

// CallContext mocks the ethereum client RPC calls used by chainlink, copying the
// return value into result.
// The simulated backend cannot access old blocks and will return an error if
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like the 1st paragraph here needs to be deleted?
The next para seems the right description as per this change

@@ -459,6 +512,12 @@ func (c *SimulatedBackendClient) SuggestGasPrice(ctx context.Context) (*big.Int,
}

// BatchCallContext makes a batch rpc call.
// The simulated backend cannot access old blocks and will return an error if
// anything other than `latest`, `nil`, or the latest block are passed to
Copy link
Contributor

Choose a reason for hiding this comment

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

delete 1st para here, seems outdated.

@EasterTheBunny EasterTheBunny added this pull request to the merge queue Sep 6, 2023
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Sep 6, 2023
@cl-sonarqube-production
Copy link

SonarQube Quality Gate

Quality Gate failed

Failed condition 3.3% 3.3% Coverage on New Code (is less than 80%)

See analysis details on SonarQube

@EasterTheBunny EasterTheBunny added this pull request to the merge queue Sep 6, 2023
Merged via the queue into develop with commit 3dfb527 Sep 6, 2023
@EasterTheBunny EasterTheBunny deleted the AUTO-4826/update-sim-backend branch September 6, 2023 23:13
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.

5 participants