Skip to content

Expose connected peer user-agents over RPC - #3780

Open
NimiqBlue wants to merge 1 commit into
nimiq:albatrossfrom
NimiqBlue:expose-peer-user-agents
Open

Expose connected peer user-agents over RPC#3780
NimiqBlue wants to merge 1 commit into
nimiq:albatrossfrom
NimiqBlue:expose-peer-user-agents

Conversation

@NimiqBlue

Copy link
Copy Markdown

What

This PR wires the configured Nimiq user-agent into libp2p identify and exposes the user-agents reported by connected peers through RPC.

It adds:

  • a Nimiq identify protocol constant (/nimiq/identify/0.0.1)
  • libp2p identify behaviour configured with the existing local user-agent string
  • storage of received peer agent_version strings keyed by PeerId
  • a new RPC method: getPeerUserAgents, returning (peerId, userAgent) pairs

Why

At the moment the configured user_agent appears to be local-only from an observer's point of view: it is configured and printed locally, but peer client versions are not available through RPC and did not show up in TRACE logs during a quick experiment.

For network observability tools such as public node maps, exposing reported peer versions makes it possible to show:

  • reported client version distribution
  • adoption of new releases
  • stale/outdated nodes
  • better diagnostics around network diversity

The user-agent should still be treated as self-reported metadata, similar to browser user-agents.

Verification

Ran locally:

  • cargo check -p nimiq-network-libp2p --all-features
  • cargo check -p nimiq-rpc-interface -p nimiq-rpc-server

Both completed successfully.

@jsdanielh jsdanielh left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

While I agree that this adds useful data, it only reports data of connected peers while a solution implemented on top of the discovery protocol could allow to relay this information and be able to retrieve versions of connected peers + other observed peers. The complication with this latter approach would be the backwards compatibility


let identify = identify::Behaviour::new(
identify::Config::new(IDENTIFY_PROTOCOL.to_string(), public_key)
.with_agent_version(config.user_agent.clone()),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We'd need to disable the peer cache to disallow the behaviour to add new peer addresses that can pollute kad and peer dialing

Suggested change
.with_agent_version(config.user_agent.clone()),
.with_agent_version(config.user_agent.clone()).
with_cache_size(0),

Comment thread lib/src/client.rs
let network_config = NetworkConfig::new(
identity_keypair,
peer_contact,
config.network.user_agent.to_string(),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

User agent has two issues IMO:

  • Contains much more info than what is needed.
  • Can be changed from the config file.

async fn get_address_book(&self) -> RPCResult<Vec<(String, PeerType)>, (), Self::Error>;

/// Returns user-agent strings announced by connected peers.
async fn get_peer_user_agents(&self) -> RPCResult<Vec<(String, String)>, (), Self::Error>;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We'd need to get this also implemented in the rpc-client

@NimiqBlue

Copy link
Copy Markdown
Author

While I agree that this adds useful data, it only reports data of connected peers while a solution implemented on top of the discovery protocol could allow to relay this information and be able to retrieve versions of connected peers + other observed peers. The complication with this latter approach would be the backwards compatibility

I agree that a discovery-based solution would be more complete, since it could expose versions for connected peers plus observed/discovered peers. It would also be better for network-wide observability.

My intent with this PR was narrower: expose only metadata that the local node can directly observe from currently connected peers, without changing discovery semantics or relaying extra data through the network. So the RPC result should be interpreted as “connected peer reported user-agents from this observer node”, not as a full network census.

I’m happy to adjust the naming/docs to make that limitation explicit, e.g. getConnectedPeers / “connected peers only”, and document that user-agent is self-reported.

If you think the discovery-based approach is the preferred long-term direction, I see two possible paths:

keep this PR as a small first step for local observability of direct peers;
close/rework it and instead open an issue/design discussion for propagating client metadata through discovery, including backwards compatibility concerns.
My preference would be 1, because it is useful immediately and does not preclude a better discovery-level solution later. But I’m happy to follow the maintainers’ preferred direction.

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.

2 participants