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 DropReason and DropPeer structs to pass reason string to logs about Dropping a Neighbor #5720

Open
wants to merge 13 commits into
base: develop
Choose a base branch
from

Conversation

jferrant
Copy link
Collaborator

@jferrant jferrant commented Jan 16, 2025

Closes #5714

@jcnelson
Copy link
Member

I like this approach overall. I think it may be worth consolidating DropPeer and DropNeigbor into a struct that only includes a PeerAddress and a DropReason (instead of a bare event_id or a full NeighborKey). I think at each call site where you derive a DropReason, you at least have the means of getting the PeerAddress.

Can this PR also implement a better formatter for PeerAddress, if that's what you end up using? Ideally it'd print the IPv4 or IPv6 address instead of the raw 16 byte address.

@jferrant
Copy link
Collaborator Author

jferrant commented Jan 17, 2025

I like this approach overall. I think it may be worth consolidating DropPeer and DropNeigbor into a struct that only includes a PeerAddress and a DropReason (instead of a bare event_id or a full NeighborKey). I think at each call site where you derive a DropReason, you at least have the means of getting the PeerAddress.

Can this PR also implement a better formatter for PeerAddress, if that's what you end up using? Ideally it'd print the IPv4 or IPv6 address instead of the raw 16 byte address.

Can do! EDIT: just a quick question, does this mean the event_id is not really relevant for matching on a neighbor key? just the neighbor_key.addrbytes, i.e. PeerAddress? Specifically...can multiple neighbor_keys with the same peer_address (even if sep port) match to the same event_id... Cause then it might not be so straightforward cause deregister_peer highly relies on event_id.

For example I see this in deregister_peer which makes me think that there are multiple matching neighbor keys per event id...

        let mut nk_remove: Vec<(NeighborKey, Hash160)> = vec![];
        for (neighbor_key, ev_id) in self.events.iter() {
            if event_id == ev_id {
                let pubkh = self
                    .get_p2p_convo(event_id)
                    .and_then(|convo| convo.get_public_key_hash())
                    .unwrap_or(Hash160([0x00; 20]));
                nk_remove.push((neighbor_key.clone(), pubkh, event_id));
            }
        }

…mplementation of fmt::Display

Signed-off-by: Jacinta Ferrant <[email protected]>
@jcnelson
Copy link
Member

Can do! EDIT: just a quick question, does this mean the event_id is not really relevant for matching on a neighbor key? just the neighbor_key.addrbytes, i.e. PeerAddress? Specifically...can multiple neighbor_keys with the same peer_address (even if sep port) match to the same event_id... Cause then it might not be so straightforward cause deregister_peer highly relies on event_id.

event_id is an opaque handle to the socket connected to the neighbor, which is used by mio to indicate which sockets are ready for read or write. It's not logged at the info level, so logging it for add/drop peers doesn't help us identify the peer being added/dropped.

The system won't register a new socket to a peer that already has a socket open, so there won't be multiple peer_addresses with the same event_id. The code in deregister_peer is defensively written; the local nk_remove list that gets built up in the function body should only ever have at most one element. You could get the NeighorKey for the given the event_id from the nk_remove list.

@aldur aldur added this to the 3.1.0.0.5 milestone Jan 22, 2025
@jferrant
Copy link
Collaborator Author

Can do! EDIT: just a quick question, does this mean the event_id is not really relevant for matching on a neighbor key? just the neighbor_key.addrbytes, i.e. PeerAddress? Specifically...can multiple neighbor_keys with the same peer_address (even if sep port) match to the same event_id... Cause then it might not be so straightforward cause deregister_peer highly relies on event_id.

event_id is an opaque handle to the socket connected to the neighbor, which is used by mio to indicate which sockets are ready for read or write. It's not logged at the info level, so logging it for add/drop peers doesn't help us identify the peer being added/dropped.

The system won't register a new socket to a peer that already has a socket open, so there won't be multiple peer_addresses with the same event_id. The code in deregister_peer is defensively written; the local nk_remove list that gets built up in the function body should only ever have at most one element. You could get the NeighorKey for the given the event_id from the nk_remove list.

Perfect! This was my only concern I think. so I should be able ot make this work.

@jferrant jferrant marked this pull request as ready for review January 22, 2025 19:16
@jferrant jferrant requested a review from a team as a code owner January 22, 2025 19:16
@jferrant jferrant changed the title Add DropReason, DropPeer, and DropNeighbor structs and do first pass … Add DropReason and DropPeer structs to pass reason string to logs about Dropping a Neighbor Jan 22, 2025
@jcnelson
Copy link
Member

A couple things you could add here, potentially:

  • could you log from what subsystem the peer was dropped by?
  • it might be worthwhile to only log peers' acceptance after they've completed a handshake, since we often get peers that connect but never authenticate (e.g. because they're on a different network).

@jferrant jferrant marked this pull request as draft January 23, 2025 19:55
@jferrant
Copy link
Collaborator Author

jferrant commented Jan 23, 2025

@jcnelson I tried to combine DropPeer and DropNeighbor but I had a really hard time replacing it in much of the code base as the neighbor key is used to deregister and ban neighbors and it seems like a LOT of the code is based on the nieghbor key itself, not just the PeerAddress. I don't mind trying to refactor this code, but it will be substantial and I am worried that we might introduce bugs as the PeerAddress would ignore ports whereas NeighborKey would not.

Also, when you say "only log peers' acceptance after they've completed a handshake", do you mean maybe remove the "Neighbor accepted log" since we already have a debug log:

        debug!(
            "{:?}: Registered {} as event {} ({:?},outbound={})",
            &self.local_peer, &client_addr, event_id, &neighbor_key, outbound
        );

And then attempt to add an info level log in handle_handshake_accept and handle_handshake in chat.rs? I don't think I could gaurantee that we won't log a "dropping neighbor" for an unauthenticated neighbor though. Would need to include a bool in the DropNeighbor/DropPeer structs to prevent printing it when it as an unauthenticated connection.

Signed-off-by: Jacinta Ferrant <[email protected]>
stackslib/src/net/p2p.rs Outdated Show resolved Hide resolved
jcnelson
jcnelson previously approved these changes Jan 31, 2025
Copy link
Member

@jcnelson jcnelson left a comment

Choose a reason for hiding this comment

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

This LGTM; just had one minor comment.

@jferrant jferrant marked this pull request as ready for review February 5, 2025 02:48
@jferrant jferrant requested a review from a team as a code owner February 5, 2025 02:48
@jferrant jferrant requested a review from jcnelson February 5, 2025 02:48
Copy link
Contributor

@obycode obycode left a comment

Choose a reason for hiding this comment

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

I think this looks good, just two minor comments.


### Changed

- Logging improvements:
- P2P logs now includes a reason for dropping a peer or neighbor
- Imrpovements to how a PeerAddress is logged (human readable format vs hex)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
- Imrpovements to how a PeerAddress is logged (human readable format vs hex)
- Improvements to how a PeerAddress is logged (human readable format vs hex)

@@ -2301,6 +2302,7 @@ impl PeerNetwork {
stats.done
);
if !stats.done {
// TODO: the result of this match doesn't seem to be used? is that intentional?
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 this result is intentionally ignored. @jcnelson can you confirm?

Copy link
Member

Choose a reason for hiding this comment

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

Yes; this was written in a time when I was a lot less idiomatic in my Rust code and when we didn't really prioritize conforming to it.

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.

4 participants