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

feat: add paginated logs #1285

Merged
merged 3 commits into from
May 23, 2022
Merged

Conversation

meetmangukiya
Copy link
Contributor

@meetmangukiya meetmangukiya commented May 19, 2022

Closes #954

Motivation

Solution

Implement a new stream that breaks requested block range into smaller pages that are loaded one at a time and streamed to the user.

Note: this only solves block limitations, if an rpc provider limits to 1000 blocks for instance, you could set page size to 1000 to solve it. However, if the limitation is on the number of logs(infura), this can't solve it automatically or completely, can try smaller page sizes but because number of logs in arbitrary block ranges is also arbitrary it can be hard to decide on a page size.

PR Checklist

  • Added Tests
  • Added Documentation
  • Updated the changelog

@meetmangukiya meetmangukiya marked this pull request as draft May 19, 2022 15:39
@meetmangukiya meetmangukiya force-pushed the 954-paginated-logs branch 4 times, most recently from 5e850c9 to 28ac213 Compare May 19, 2022 16:57
@meetmangukiya meetmangukiya marked this pull request as ready for review May 19, 2022 17:22
Copy link
Owner

@gakonst gakonst left a comment

Choose a reason for hiding this comment

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

looks good - i think we need a test to ensure it works appropriately, either with a local node or with a large mainnet/testnet query?

Comment on lines +427 to +434
/// Returns a stream of logs are loaded in pages of given page size
fn get_logs_paginated<'a>(
&'a self,
filter: &Filter,
page_size: u64,
) -> LogQuery<'a, Self::Provider> {
self.inner().get_logs_paginated(filter, page_size)
}
Copy link
Owner

Choose a reason for hiding this comment

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

@prestwich wdyt about unifying this logic in the default get_logs behavior?

Copy link
Collaborator

Choose a reason for hiding this comment

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

i think it's a pretty reasonable way to smooth over inconsistent RPC paging requirements 🤔

@meetmangukiya
Copy link
Contributor Author

looks good - i think we need a test to ensure it works appropriately, either with a local node or with a large mainnet/testnet query?

Ah actually i tested with an example seems like i missed committing.

ethers-providers/src/log_query.rs Outdated Show resolved Hide resolved
ethers-providers/src/log_query.rs Show resolved Hide resolved
Copy link
Owner

@gakonst gakonst left a comment

Choose a reason for hiding this comment

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

LGTM. Separately, I wonder if we should unify this with get_logs. Would be a breaking change, requiring to change the function signature to return LogQuery instead of Vec<Log> but that could be navigable as it'd basically only introduce an additional await when iterating over the vector of logs.

Is there any benefit to using get_log over always using paginated? Probably not?

@gakonst gakonst merged commit a150666 into gakonst:master May 23, 2022
@meetmangukiya
Copy link
Contributor Author

Yeah, no real benefits of using get_log, didn't change it to not break things

@gakonst
Copy link
Owner

gakonst commented May 24, 2022

Would give the follow-up a try, I think this is a good enough change that it's worth breaking, and we can include in the changelog

}
LogQueryState::LoadLogs(fut) => {
let logs = futures_util::ready!(fut.as_mut().poll(ctx))
.expect("error occurred loading logs");
Copy link
Contributor

Choose a reason for hiding this comment

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

Panicking on failed RPCs is not very nice. I'd much prefer if this was a TryStream instead. Will submit PR when I get to it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Implemented TryStream along with other fixes here 0143caf

mattsse pushed a commit to mattsse/ethers-rs that referenced this pull request May 28, 2022
* feat: add paginated logs

* docs: add paginated_logs example

* remove unpin
return Poll::Ready(None)
}
// load next page
self.from_block = Some(to_block);
Copy link

@philsippl philsippl May 29, 2022

Choose a reason for hiding this comment

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

This should be to_block + 1, otherwise you double-sync blocks at the boundaries.

Copy link
Owner

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

will verify this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@philsippl is correct, will fix this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

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.

Pagination / Streaming for Event Logs
6 participants