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

Turn lite::types::Requester into an async trait #171

Merged
merged 1 commit into from
Mar 11, 2020

Conversation

romac
Copy link
Member

@romac romac commented Mar 10, 2020

Closes: #170

On top of the changes mentioned in the linked issue, lite::verifier::verify_bisection_inner had to be manually adapted to return a boxed future because recursive async fn are not currently supported in Rust.

An possible alternative would be to rewrite verify_bisection_inner to not be recursive anymore, but that is outside of the scope of this PR.

  • Referenced an issue explaining the need for the change
  • Updated all relevant documentation in docs
  • Updated all code comments where relevant
  • Wrote tests
  • Updated CHANGES.md

Requester not being an async trait forced implementations
to block on RPC queries, eg. by spawning a new executor,
which is undesirable considering that we eventually want
the whole codebase to play nice with async/.await,
and not unnecessarily block the enclosing task.

Because trait cannot currently define async functions, this commit
introduces a dependency on the `async-trait` crate, which turns
async fns within traits and their implementations into plain
functions returning `Pin<Box<dyn Future<Output = T + ...>>>`.

The obvious drawback of this approach is that these async fns now
allocate memory on the heap. Hopefully, the language will soon
stabilize the feature, which will help us get rid of these
undesirable heap allocations.

On top of that, the `lite::verifier::verify_bisection_inner` fn had
to be manually adapted to return a boxed future because recursive
async fn are not currently supported in Rust.

An possible alternative would be to rewrite `verify_bisection_inner`
to not be recursive anymore, but that is outside of the scope of
this commit.
) -> Result<TrustedState<C, H>, Error>
req: &'a R,
mut cache: &'a mut Vec<TrustedState<C, H>>,
) -> LocalBoxFuture<'a, Result<TrustedState<C, H>, Error>>
Copy link
Member

Choose a reason for hiding this comment

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

It is a bit unfortunate that the we had to change the method signature to return a boxed future. But this change is good in the sense that it surfaces that there is still a too tight coupling between verification logic and the requester (or networking / IO).

@brapse also suggested yesterday that we should probably implement the iterative version here too. It seems like this is a good idea for several reasons now.

Copy link
Member

Choose a reason for hiding this comment

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


fn main() {
#[tokio::main]
async fn main() {
Copy link
Member

Choose a reason for hiding this comment

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

I can look into incorporating these changes into the abscissa version of this main (in #125) likely with abscissa_tokio as @tarcieri suggested.

tokio = "0.2"

async-trait = "0.1"
tokio = { version = "0.2", features = ["full"] }
Copy link
Member

Choose a reason for hiding this comment

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

Just to double check: do we need all Tokio public API features? Is there a good reason to enable them all anyways?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah sorry, macros should be sufficient (as in #173).

Copy link
Member

@liamsi liamsi left a comment

Choose a reason for hiding this comment

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

Thanks a lot @romac. The changes LGTM 👍

@liamsi liamsi merged commit 00873bd into master Mar 11, 2020
@liamsi liamsi deleted the romac/async-requester branch March 11, 2020 09:12
#[test]
fn test_verify_single_skip_1_val_verify() {
#[tokio::test]
async fn test_verify_single_skip_1_val_verify() {
Copy link
Member

Choose a reason for hiding this comment

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

Do the tests which don't use async functions need to be async?

Copy link
Member

Choose a reason for hiding this comment

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

No, they don't. Maybe this wasn't intentional (only the bisection test use async functions).

Copy link
Member

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.

Turn lite::types::Requester into an async trait
3 participants