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

Add a way to fetch transactions in P2P without specifying a peer #2376

Merged
merged 8 commits into from
Oct 31, 2024

Conversation

AurelienFT
Copy link
Contributor

Linked Issues/PRs

This is a requirement for #2361

Description

This PR adds a way to fetch transactions with p2p but without giving a specific peer and let p2p choose the one they prefer.
This will be used in #2361

Checklist

  • Breaking changes are clearly marked as such in the PR description and changelog
  • New behavior is reflected in tests
  • The specification matches the implemented behavior (link update PR if changes are needed)

Before requesting review

  • I have reviewed the code myself
  • I have created follow-up issues caused by this PR and linked them here

@AurelienFT AurelienFT changed the title Add a way to fetch transactions without specifying a peer in P2P Add a way to fetch transactions in P2P without specifying a peer Oct 21, 2024
@AurelienFT AurelienFT marked this pull request as ready for review October 21, 2024 12:41
Comment on lines 870 to 873
let peer = self.p2p_service.get_peer_id_with_height(&height);
if self.p2p_service.send_request_msg(peer, request_msg, channel).is_err() {
tracing::warn!("No peers found for block at height {:?}", block_height_range.end);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

If peer is None, you need return an error instead of printing the log.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. I followed the pattern from the headers should I change the headers one ?

block_height_range: Range<u32>,
channel: OnResponse<Option<Vec<Transactions>>>,
},
GetTransactionsFromPeer {
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 we can remove this variant

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 think it's useful in case of syncing when you already received the header from someone in the current syncing process and so you can directly ask him without having to redo peer selection. Maybe there is also othhers use cases but this is the only one I see.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems that after your PR we don't need this variant anymore. But we can address it in your PR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Mhhh yeah let's discuss it in the other PR because IMO what I have written above still works in certain cases.

acerone85
acerone85 previously approved these changes Oct 22, 2024
Copy link
Contributor

@acerone85 acerone85 left a comment

Choose a reason for hiding this comment

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

LGTM

Dentosal
Dentosal previously approved these changes Oct 23, 2024
block_height_range: Range<u32>,
channel: OnResponse<Option<Vec<Transactions>>>,
},
GetTransactionsFromPeer {
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems that after your PR we don't need this variant anymore. But we can address it in your PR

let request_msg = RequestMessage::Transactions(block_height_range.clone());
let height = BlockHeight::from(block_height_range.end.saturating_sub(1));
let peer = self.p2p_service.get_peer_id_with_height(&height);
if self.p2p_service.send_request_msg(peer, request_msg, channel).is_err() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should return error to the channel if peer is None, to allow proper handling of it by the caller.

Copy link
Contributor Author

@AurelienFT AurelienFT Oct 29, 2024

Choose a reason for hiding this comment

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

I can change it, ok. However, I want to ask if we want the same in GetSealedHeaders (just above in the code) ? It has the same behavior and doesn't return the error for now.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yep, good catch, let's fix it as well

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. It complexify a bit the type in the channel because we have a two-stage error type but with unification of return type etc that we want to do in p2p maybe we could improve this in the future.

Comment on lines +1075 to +1080
self.request_sender
.send(TaskRequest::GetTransactions {
block_height_range: range,
channel: sender,
})
.await?;
Copy link
Member

Choose a reason for hiding this comment

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

perhaps we should continue to use the TaskRequest::GetTransactionsFromPeer and perform peer selection for a given block height instead -

fn get_peer_id_with_height(&self, height: &BlockHeight) -> Option<PeerId> {
self.peer_manager().get_peer_id_with_height(height)
}

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 personally think that there is still use case where it's interesting to already give a peer that we know have the information, we use this un sync service.

Copy link
Member

Choose a reason for hiding this comment

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

right, i agree ~ but this information is also valid for a peer returned by get_peer_id_with_height. perhaps we should not duplicate valid peers for a given height then.

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 don't get your comment. My flow is that I ask for an header and so the peer is returned along with the header then I can directly ask to this peer about the transactions because in our network if you have the header we assume you have the transactions. It avoid running this get_peer_id_with_height function that can be costly.
Maybe I miss your point and in this case we can go over more voice discussion :)

Copy link
Collaborator

Choose a reason for hiding this comment

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

perhaps we should continue to use the TaskRequest::GetTransactionsFromPeer and perform peer selection for a given block height instead

If we do peer selection outside of the run loop, we can face race condition were peer is disconnected already

@AurelienFT AurelienFT requested a review from rymnc October 31, 2024 00:21
@AurelienFT AurelienFT merged commit 32b29a3 into master Oct 31, 2024
38 checks passed
@AurelienFT AurelienFT deleted the add_p2p_fetch_txs_no_peer_specified branch October 31, 2024 08:47
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