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 block-ref to not make duplicate request #151

Merged
merged 4 commits into from Oct 3, 2022
Merged

Conversation

mcmire
Copy link
Contributor

@mcmire mcmire commented Sep 30, 2022

The goal of the block-ref middleware is to look for instances in request parameters where "latest" is being used as a block parameter and replace it with the actual latest block number (as reported by the block tracker). The middleware will then make a child request through the provider using the resolved parameters and copy the child response onto the final response object.

That is fine; however, this middleware then calls the next middleware in the stack, which in practice will make another request, and that will end up overwriting the child response set in this middleware. That makes this middleware ineffective.

So, this commit removes the next() call from the block-ref middleware so that when it takes effect it stops the chain and prevents an extra request.

In addition, this fills in missing tests for the middleware by reusing some test helpers from a previous PR.


Fixes #142.

The goal of the `block-ref` middleware is to look for instances in
request parameters where "latest" is being used as a block parameter and
replace it with the actual latest block number (as reported by the block
tracker). The middleware will then make a child request through the
provider using the resolved parameters and copy the child response onto
the final response object, which will be carried to the next middleware
in the stack.

However, this behavior is unnecessary, and in fact it makes this
middleware useless, because in practice, the next middleware will end up
making a request on its own, overwriting the child response gathered in
this middleware.

This commit changes the `block-ref` middleware so that it will apply the
"latest" replacement mentioned above by changing the request parameters
in place before proceeding to the next middleware. This should retain
the existing behavior but avoid making an extra request.

In addition, this fills in missing tests for the middleware by reusing
some test helpers from a previous PR.
@mcmire mcmire requested a review from a team as a code owner September 30, 2022 00:29
src/block-ref.ts Outdated
res.result = childRes.result;
res.error = childRes.error;

req.params[blockRefIndex] = latestBlock;
Copy link
Member

Choose a reason for hiding this comment

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

It looks like you've changed how this works by rewriting the original request, rather than sending a child request.

If that's what we want to do, that's what the block-ref-rewrite middleware already does. So I'm not sure we want to make block-ref work like that too. Not unless we're confident we would only need one, and we want to consolidate them both.

I'm not entirely sure why the two cases were split like that, or why we moved to using this strategy.

Copy link
Contributor Author

@mcmire mcmire Sep 30, 2022

Choose a reason for hiding this comment

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

Sigh... that's very strange...

Okay, I've reverted the behavior and fixed up the tests accordingly: 737f54e

it('makes a direct request through the provider, replacing the block param with the latest block number', async () => {
await withTestSetup(
{
configureMiddleware: ({ provider, blockTracker }) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a slightly different style compared with the retryOnEmpty tests I wrote earlier. I wanted to make it so that:

  • It's obvious what the middleware-under-test is. Previously this was automatically added in a helper function, now it happens within each test explicitly. Yet, it's drawn out so it's easier to see.
  • If you don't need to supply a final middleware (because you're not testing that the middleware-under-test is calling the next middleware), you don't need to supply an extra option like withFinalMiddleware: false. At the same time, a default middleware is still pushed onto the engine. The purpose of this default middleware is to serve as a reminder for the developer in case the middleware-under-test attempts to call the next middleware and that was unexpected.
  • If you do need to supply a final middleware because you want to test that it gets called, then you can still do that easily.

* @param callback - A function.
* @returns Whatever the function returns.
*/
async function withTestSetup<T>(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

A lot of the helper functions here were copied from the tests for retryOnEmpty. I plan on introducing another PR after this one which will extract these helpers from the two files.

Copy link
Member

@Gudahtt Gudahtt left a comment

Choose a reason for hiding this comment

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

LGTM!

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.

[block-ref] Duplicate request sent when latest or undefined block number given
2 participants